java - Jaxb:如何解码 xs:任何 XML 字符串部分?

标签 java xml jaxb

我有一个应用程序使用 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 并放入 any (org.apache.xerces.dom.ElementNSImpl) 元素以构建 Java 对象?

另外,下一种情况是当我将此元素作为 java 时,我想解码这部分(以便能够提取此元素的 XML 字符串)。但这是不可能的。我得到一个关于根元素的异常(exception)。但是不能对 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.in​​dex 资源:

com.acme.foo.MyClass

然后将你的包名添加到上下文路径中:

JAXBContext context = JAXBContext.newInstance("org.dar.gee.schema:com.acme.foo");

ObjectFactory 等还有其他方法,但 jaxb.in​​dex 的技巧可能是最简单的方法。

或者,您可以将 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/9687588/

相关文章:

java - tomcat7-maven-插件 : run multiple webapps but port 8080 already in use

Java处理ClassNotFoundException

Java 套接字 - 并行运行同一客户端多次。

java - 在 JBoss 中使用 MOXy 创建 JAXBContext 时出现 StackOverflow 错误

java - Maven 依赖 Netty - NoSuchMethodError

xml - Scala 填充模板的方式?

java - 尝试将 XML 映射到 POJO 时出现 "unexpected element"

xml - XML 包含多个命名空间 - 但它只有一个

java - 具有默认无参数构造函数时出现解码错误 Jaxb - "Class does not have a default no arg constructor"

java - xml:JAXB 中的基础