我有一个应用程序使用 Jaxb 进行 XML<-> 转换,并使用 maven-jaxb2-plugin 自动生成类。
在我的模式深处的某个地方,我可以输入“ANY”xml。
更新:这更好地描述了我的架构。一些已知的 XML 包装了完全未知的部分(“任何”部分)。
<xs:complexType name="MessageType">
<xs:sequence>
<xs:element name="XmlAnyPayload" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:any namespace="##any"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="OtherElements">
....
</xs:sequence>
这(由 jaxb)映射到这样的内部类。
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"any"
})
public static class XmlAnyPayload {
@XmlAnyElement(lax = true)
protected Object any;
当我解码整个结构时,没有问题。 “Object any”将呈现为 org.apache.xerces.dom.ElementNSImpl。现在,我想手动重新创建 Java 对象,然后转到 XML。如何获取一些随机 XML 并将其放入任何 (org.apache.xerces.dom.ElementNSImpl) 元素中以便能够构建 Java 对象?
另外,下一种情况是当我将此元素作为 java 时,我想解码这一部分(以便能够提取此元素的 XML 字符串)。但这是不可能的。我得到一个关于根元素的异常。但无法注释 ElementNSImpl。
unable to marshal type "com.sun.org.apache.xerces.internal.dom.ElementNSImpl" as an element because it is missing an @XmlRootElement annotation
您对如何处理这些问题有什么建议吗?
最佳答案
@XmlAnyElement(lax = true)
用简单的英语表示,如下所示:
Dear JAXB! If you have a mapping for this element, please unmarshal it into a Java object. If you don't know this element, just leave it as a DOM element.
这正是您的情况所发生的情况。因此,如果您想实际解码此 lax any 的内容,请为 JAXB 上下文提供您希望解码的元素的映射。最简单的方法是使用 @XmlRootElement
@XmlRootElement(name="foo", namespace="urn:bar")
public class MyClass { ... }
现在,当您创建 JAXB 上下文时,将 MyClass
添加到其中:
JAXBContext context = JAXBContext.newInstance(A.class, B.class, ..., MyClass.class);
在这种情况下,如果 JAXB 在 xs:any
的位置遇到 {urn:bar}foo
元素,它就会知道该元素已映射到 MyClass
上,并将尝试解码 MyClass。
如果您根据包名称创建 JAXB 上下文(您可能会这样做),您仍然可以向其中添加类(例如,com.acme.foo.MyClass
)。最简单的方法是创建一个 com/acme/foo/jaxb.index
资源:
com.acme.foo.MyClass
并将您的包名称添加到上下文路径:
JAXBContext context = JAXBContext.newInstance("org.dar.gee.schema:com.acme.foo");
还有其他方法可以使用 ObjectFactory
等,但使用 jaxb.index
的技巧可能是最简单的一种。
或者,您可以将 xs:any
的内容保留为 DOM,并在使用另一个 JAXB 上下文(知道您的 MyClass
类)的第二次解码中将其解码到目标对象中,而不是在一次运行中解码所有内容。像这样的东西:
JAXBContext payloadContext = JAXBContext.newInstance(MyClass.class);
payloadContext.createUnmarshaller().unmarshal((Node) myPayload.getAny());
这种方法有时更好,特别是当您拥有相对独立的容器/有效负载模式的组合时。视具体情况而定。
上述所有内容也适用于编码。这一切都是双向的。
关于java - Jaxb:如何解码 xs:任何 XML 字符串部分?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52247004/