当前位置: 首页 > 知识库问答 >
问题:

如何防止JAXB在编组期间写入未使用的名称空间

师建德
2023-03-14

有人曾经能够使用JAXB在对象列表中删除未使用的命名空间吗?这是请求功能的链接:https://github.com/javaee/jaxb-v2/issues/103(见描述)

是否有用于为此配置 JAXB 的属性?这个问题在MOXy中是否已修复?

我目前正在遍历需要封送的对象,并提取所有需要绑定到Class[]类ToBeBound中的类。然后我创建一个新的JAXBContext.newInstance(classesToBeBound)

未使用的名称空间现在不包含在XML中。

我知道即使使用未使用的名称空间,xml验证也是有效的,但对我来说,这是框架应该处理的事情。

以下链接https://blogs.oracle.com/enterprisetechtips/entry/customizing_jaxb提到各种固定的(见文本中间的某个地方),但当试图在这些链接中找到解决方案时,要么链接断开,要么没有人真正解决。

欢迎提出任何意见。

(编辑)纯文本:

鉴于

a new instance of JAXBContext and add 2 classes with each a separate namespace. 

marshalling a class that has these 2 classes as a property but only 1 of them is not null 

然后

I expect only the namespace of the property that is not null to be visible in the XML. 

但事实是

that both namespaces are in the xml. 

因此,我的问题是如何删除或告诉JAXB不要编写未使用的名称空间?

把它放在java代码中:给定

public class Foo{
  private Bar bar; //namespace something2
  private User user; //namespace user
}

当...的时候

JAXBContext c = JAXBContext.newInstance(Foo.class, Bar.class, User.class);
...
Foo foo = new Foo();
foo.setBar(null);
foo.setUser(new User("Bob"));
marshaller.umarshal(foo);

那么我希望xml是

<foo xmlns="something1"  xmlns:user="user">
  <user:name>Bob</user:name>
</foo>

但实际的是(注意something2名称空间)

<foo xmlns="something1" xmlns:user="user" xmlns:bar="something2">
  <user:name>Bob</user:name>
</foo>

当然,这是一个简化的示例,我们对类型的规范有大约30个不同的名称空间。

共有3个答案

翟奇逸
2023-03-14

您可以尝试使用不同的javax.xml.bind.Marshaller实现。

例如,org.eclipse.persistence.jaxb.JAXBMarshaller实现很好地处理了这种情况,并在编组对象时删除了所有不必要的命名空间。

为此,您需要执行以下步骤:

    < li >将eclipselink-2.6.5.jar添加到类路径中,以便使用< code > org . eclipse . persistence . JAXB . JAXB marshaller 。如果您使用的是gradle,您可以将< code > compile ' org . eclipse . persistence:eclipse link:2 . 6 . 5 ' 添加到您的依赖项中。 < li >在包含要整理的对象的同一个包中创建< code>jaxb.properties文件(按照问题中的示例-< code > JAXB context c = JAXB context . new instance(foo . class,Bar.class,user . class));,在这些类之一的包中< code>Foo、< code>Bar或< code>User。 < li >在< code>jaxb.properties文件中,添加指定所需上下文工厂的以下属性:
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory 

这样,org.eclipse.persistence.jaxb.JAXBMarshaller将被用作运行时上的javax.xml.bind.Marshaller实现。然后,当您整理对象时,不会出现不必要的命名空间。

唐兴思
2023-03-14

这可能是不可能的,因为在此对象层次结构的封送处理发生时,在创建根标记时,关于哪些对象为空v/s not null的信息可能不可用。在调用相应的访问器方法时,任何提前获取该信息的尝试也可能会有与之相关的副作用。因此JAXB将静态地使用来自JAXBContext的信息来填充这些信息。

海岳
2023-03-14

据我所知,这在JAXB中确实是不可能的 - 实际上是一个众所周知的问题。正如您所注意到的,生成的命名空间列表是在 JAXBContext 中注册的命名空间,而不是在编组时有效使用的命名空间:-(

在过去,我使用了与您相同的解决方法(识别各种使用的类并将JAXBContext缩小到这组有限的类)。

另一个典型的解决方法是两步处理:首先使用 JAXB 进行编组,然后进行 XSLT 转换以摆脱“污染”命名空间。

 类似资料:
  • 问题内容: 我的架构指定了一个名称空间,但是文档没有。在JAXB解组(XML-> object)期间忽略名称空间的最简单方法是什么? 换句话说,我有 代替, 问题答案: 我相信你必须将名称空间添加到xml文档中,例如,使用SAX过滤器。 这意味着: 用一个新类定义一个ContentHandler接口,该接口将在JAXB获得它们之前拦截SAX事件。 定义一个XMLReader,它将设置内容处理程序

  • 我的代码如下: 我怎样才能让它工作?如果我的xml标记有一些相关元素,如上面的“xmlns”,则JAXB解组器会抛出异常。 这是我第一次这么做,所以我对JAXB、解编等都一无所知。我在苦苦挣扎任何帮助都是好的。 编辑StackTrace:

  • 这是我的xml,需要把它转换成Java。我使用了jaxb 并抛出以下异常javax.xml.bind.unmarshalException:意外元素(URI:“http://www.ae.com/event/load”,local:“order”)。需要的元素为<{}LM:order>

  • 问题内容: 这是我的xml,需要将其转换为Java。我用过jaxb 并引发以下异常javax.xml.bind.UnmarshalException:意外元素(uri:“ http://www.ae.com/Event/Load ”,本地:“ Order”)。期望的元素是<{} lm:Order> 这是我的解组代码 订购Pojo班 您能否也帮助我阅读,当前正在读取文件,需要读取为XML Strin

  • 我在名称空间方面有问题。我需要从一个公共api (Prestashop)解组。该api使用xml作为xlink类型,如下所示: 每种产品的 API 为: 我为每个XML生成了两个包含pojo类的包。我想从产品列表中获取给定id的任何产品的属性。 我有一个产品,其中包含@XMLSchema命名空间,但这个命名空间仅针对一个路径是静态的。我知道这不是这样做的方法。 下面,我的客户类。 这里有代码:ht

  • 首先,我使用Camel 2.15版(在Fuse 6.2.1中)创建了一些路由。 在我的过程中,我试图从使用cxf xjc maven插件生成的pojo中创建一个XML(cxf xjc从xsd的某个地方读取了一些xsd,然后生成了带有jaxb注释的pojo)。 pojos是TempProject和TempProjects。 我可以使用以下代码生成xml: 我打电话 在我实现从pojo到xml的编组的