首页 > 解决方案 > JAXB 绑定 3 级嵌套元素

问题描述

我正在尝试使用 jaxb 将以下 xml 绑定到 java

<Validation> 
...
        <Options>
             <AllowUnspecifiedParameters>
                  <Header> True </Header>
                  <Query> True </Query>
                  <Cookies> True </Cookies>
             </AllowUnspecifiedParameters>
        </Options>
</Validation> 

我见过一些类似的例子,比如JAXB 绑定嵌套元素 但是最深的嵌套级别是列表,@XmlElementWrapper 仅用于集合,所以它看起来不适合我的情况。

有谁知道我该怎么做?真的很感激。

标签: javaxmljaxbmarshallingunmarshalling

解决方案


选项 1一种纯粹的 JaxB 方法是通过为 Options 元素定义适配器。适配器用于或多或少地将任何 xml 转换为任何对象,反之亦然(自定义编组)。

    @XmlJavaTypeAdapter(OptionsAdapter.class)

    public class OptionsAdapter extends extends XmlAdapter<Element, Options> {

    @Override
        public Element marshal(Options v) throws Exception {
            // put your marshaling logic here
        }

        @Override
        public Options unmarshal(Element node) throws Exception {
           // put your unmarshaling logic here
        }

    }

Then in the class holding the options element you will have:

    public class ClazzHoldingOptions {

      @XmlJavaTypeAdapter(OptionsAdapter.class)
      private Options options;

    }

选项 2 EclipseLink 具有通过 xpath 表达式映射元素的功能

     @XmlPath("AllowUnspecifiedParameters/Header/text()")
     private String  header;

https://www.eclipse.org/eclipselink/api/2.4/org/eclipse/persistence/oxm/annotations/XmlPath.html

选项 3在阅读 @df778899 的代码时,我认为他的解决方案不是最优的,但它解决了我迄今为止尚未解决的问题。当您拥有太多属性时,您实际上不想映射它们,或者您根本无法控制 XML 内容并且不信任它并且不想进行破坏性更改。我将在其中映射到 HashMap:

    @XmlJavaTypeAdapter(OptionsAdapter.class)

    public class OptionsAdapter extends extends XmlAdapter<Element, Options> {

    @Override
        public Element marshal(Hashmap v) throws Exception {
            // put your marshaling logic here
        }

        @Override
        public HashMap unmarshal(Element node) throws Exception {
           // put your unmarshaling logic here
        }

    }

Then in the class holding the options element you will have:

    public class ClazzHoldingOptions {

      @XmlJavaTypeAdapter(OptionsAdapter.class)
      private HashMap options;

    }

概括。所以让我总结一下优点和缺点

选项 1。 +标准方法纯 jaxB +如果您可以控制自己的 xml 文件架构,则很好。或者,如果架构预计不会每月更改。- 如果架构或 xml 文件非常不稳定,则不好。

选项 2。 +非常易于使用。无需适配器。- 如果您的架构易变,这也不是最佳解决方案。- 需要特定的 JaxB 实现

选项 3。-仅当您有一个 volatile xml 以避免破坏性更改时才好。

PS:我会使用类似@df778899 解决方案的唯一情况是,如果 XML 中的内容存在极端的结构不确定性。例如,如果我知道某些内容会出现在 xml 中,但我不知道具体在哪里。加上它是内存不足的,你想在内存中保存与你的 xml 相关的所有元数据。


推荐阅读