【问题标题】:JAXB mapping elements with "unknown" name具有“未知”名称的 JAXB 映射元素
【发布时间】:2010-11-25 15:21:36
【问题描述】:

我有一个无法控制生成方式的 XML。我想通过将它解组到我手写的类来创建一个对象。

其结构的一个 sn-p 如下所示:

<categories>
    <key_0>aaa</key_0>
    <key_1>bbb</key_1>
    <key_2>ccc</key_2>
</categories>

我该如何处理这种情况?当然元素的数量是可变的。

【问题讨论】:

  • XML 结构是否有明确定义的架构?
  • 没有。来源是一些 PHP REST Web 服务(这并不意味着它不能完成)。

标签: java xml jaxb unmarshalling


【解决方案1】:

如果您使用以下对象模型,则每个未映射的 key_# 元素都将保存为 org.w3c.dom.Element 的实例:

import java.util.List;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlRootElement;
import org.w3c.dom.Element;

@XmlRootElement
public class Categories {

    private List<Element> keys;

    @XmlAnyElement
    public List<Element> getKeys() {
        return keys;
    }

    public void setKeys(List<Element> keys) {
        this.keys = keys;
    }

}

如果任何元素对应于使用@XmlRootElement 注解映射的类,那么您可以使用@XmlAnyElement(lax=true) 并且已知元素将被转换为相应的对象。示例见:

【讨论】:

  • 是的,这就是解决方案。我对其进行了一些修改(删除了修改器)并将其合并为内部静态类。太好了,现在继续下一个问题......
【解决方案2】:

这样使用

        @XmlRootElement
        @XmlAccessorType(XmlAccessType.FIELD)
        public static class Categories {


            @XmlAnyElement
            @XmlJavaTypeAdapter(ValueAdapter.class)
            protected List<String> categories=new ArrayList<String>();

            public List<String> getCategories() {
                return categories;
            }
            public void setCategories(String value) {
                this.categories.add(value);
            }
        }

        class ValueAdapter extends XmlAdapter<Object, String>{

           @Override
           public Object marshal(String v) throws Exception {
              // write code for marshall
             return null;
           }

           @Override
           public String unmarshal(Object v) throws Exception {
              Element element = (Element) v;
              return element.getTextContent();
          }
       }

【讨论】:

    【解决方案3】:

    对于这个简单的元素,我将创建一个名为 Categories:

    import javax.xml.bind.annotation.XmlRootElement;
    
    @XmlRootElement
    public class Categories {
    
        protected String key_0;
        protected String key_1;
        protected String key_2;
    
        public String getKey_0() {
            return key_0;
        }
    
        public void setKey_0(String key_0) {
            this.key_0 = key_0;
        }
    
        public String getKey_1() {
            return key_1;
        }
    
        public void setKey_1(String key_1) {
            this.key_1 = key_1;
        }
    
        public String getKey_2() {
            return key_2;
        }
    
        public void setKey_2(String key_2) {
            this.key_2 = key_2;
        }
    
    }
    

    然后在一个主方法中,我会创建解组器:

    JAXBContext context = JAXBContext.newInstance(Categories.class);
    Unmarshaller um = context.createUnmarshaller();
    Categories response = (Categories) um.unmarshal(new FileReader("my.xml"));
    // access the Categories object "response"
    

    为了能够检索所有对象,我想我会将所有元素放在一个新 xml 文件中的根元素中,并使用 @XmlRootElement 注释为该根元素编写一个类。

    希望对您有所帮助, 男人

    【讨论】:

    • +1,但您不需要在 XmlRootElement 上指定名称,因为它将默认为“类别”,您也不需要使用 @XmlElement 进行注释,因为它是默认值。
    • 不。我知道如何编组和解组简单的类。也许我的问题不够清楚。上面的 XML 只是一个更大的 XML 的片段。我的问题是如何处理 元素下面的未知数量的元素。可以有 ,因此 元素下有 67 个元素。
    • key_# 元素的内容总是只是一个文本节点吗?
    • 是的,它总是一个文本节点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-13
    • 1970-01-01
    相关资源
    最近更新 更多