要映射的JAXB节点 [英] JAXB nodes to map

查看:81
本文介绍了要映射的JAXB节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个如下所示的XML文件:

I have a XML file like the following:

<root>
  <item>
    <id>my id</id>
    <type>my type</id>
    <key1>value1</key1>
    <key2>value1</key2>
    <key3>value1</key3>
  </item>

  <item>
    <id>my id</id>
    <type>my type</type>
    <other-key1>value1</other-key1>
    <other-key2>value1</other-key2>
  </item>

  (...)

</root>

我想在这样的类上解析XML:

And I want to parse the XML on a class like this:

public class Item {
    private String id;

    private String type;

    private Map<String, String> values;
}

将id节点和类型节点映射到具有相同名称的属性,并将项内的其他所有内容添加到映射.

Where the id node and the type node are mapped to the attributes with the same name and everyting else inside a item are added to a map.

我尝试编写带有注解XmlJavaTypeAdapter和XmlAnyElement的类,但这对我的期望不起作用:

I have tried write a class with the annotations XmlJavaTypeAdapter and XmlAnyElement but this does not work how I expect:

(...)

public class Item {
    @XmlElement
    private String id;

    @XmlElement
    private String type;

    @XmlAnyElement
    @XmlJavaTypeAdapter(MapAdapter.class)
    private Map<String, String> values;
}


public class MapAdapter extends XmlAdapter<Object, Map<String, String>> {
    @Override
    public Object marshal(Map<String, String> v) throws Exception {
    }

    @Override
    public Map<String, String> unmarshal(Object v) throws Exception {
        // v is a node instead an array of nodes.
        // I want to get an array of nodes to convert them to a map.
        //
        // eg:
        //  
        //   key1 -> value1
        //   key2 -> value2
        //   key3 -> value3
        //
    }

你知道我怎么能得到这个吗?

Any idea how I can get this?

我的问题的澄清:

我的问题是我要在地图中解组的元素不在包装器内,而是与同一级别的其他元素混合在一起.

My problem is that the elements that I want to unmarshal within the map are not inside a wrapper and they are mixed with another elements at the same level.

我试图使用XmlAnyElement和XmlJavaTypeAdapter来获取所有剩余元素的映射.但是这些注释上有一个隐式顺序,我得到的是用适配器解析的元素的集合:

I tried to use the XmlAnyElement and XmlJavaTypeAdapter to get a map of all the remaining elements. However there is an implicit order on these annotations and what I get is a collection of elements parsed with the adapter:

XmlAnyElement找到每个剩余的元素,用适配器对其进行解析,并将结果添加到集合中.

XmlAnyElement finds each remaining element, parse it with the adapter and add the result to a collection.

有什么办法可以扭转这种情况吗?

Is there any way to reverse this?

我想获取所有剩余元素的集合,然后使用XmlAdapter解析该集合以获取地图.

I want to get a collection of all the remaining elements and then parse the collection with the XmlAdapter to get a map.

推荐答案

就像您一样,我没有成功编写XmlAdapter. 但是还有另一种可能的方法:

Like you I didn't succeed in writing an XmlAdapter. But there is another possible approach:

在您的Item类中,声明一个用@XmlAnyElement注释的List<Element>, 以便JAXB将其用于编组/解组.

In your Item class declare a List<Element> annotated with @XmlAnyElement, so that JAXB will use it for marshalling/unmarshalling.

但是您想要一个Map<String, String>.因此,您也声明了这一点, 但用@XmlTransient注释,以便JAXB不会将其用于编组/解组.

But you want a Map<String, String>. Hence you declare that too, but annotated with @XmlTransient, so that JAXB will not use it for marshalling/unmarshalling.

最后实现一个私有方法afterUnmarshal(Unmarshaller unmarshaller, Object parent) 在其中将内容从List<Element>铲到Map<String, String>. 如中所述 解组事件回调 JAXB将在适当的时候调用此方法.

Finally implement a private method afterUnmarshal(Unmarshaller unmarshaller, Object parent) where you shovel contents from the List<Element> to the Map<String, String>. As described in Unmarshal Event Callbacks JAXB will call this method at appropriate times.

如果您需要编写XML文件 您可能还需要一个私有方法beforeMmarshal(Marshaller marshaller) 在其中将内容从Map<String, String>铲回到List<Element>. 如中所述 元帅事件回调 JAXB将在适当的时候调用此方法.

If you need to write XML files you may also need a private method beforeMmarshal(Marshaller marshaller) where you shovel contents from the Map<String, String> back to the List<Element>. As described in Marshal Event Callbacks JAXB will call this method at appropriate times.

public class Item {

    @XmlElement
    private String id;

    @XmlElement
    private String type;

    @XmlAnyElement
    private List<Element> otherElements;

    @XmlTransient  // don't participate in JAXB marshalling/unmarshalling
    private Map<String, String> values;

    @SuppressWarnings("unused")   // called only by JAXB
    private void afterUnmarshal(Unmarshaller unmarshaller, Object parent) {
        values = new HashMap<>();
        if (otherElements != null) {
            for (Element element : otherElements) {
                String key = element.getNodeName();
                String value = element.getFirstChild().getNodeValue();
                values.put(key, value);
            }
        }
    }

}

这篇关于要映射的JAXB节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆