要映射的JAXB节点 [英] JAXB nodes to map
问题描述
我有一个如下所示的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屋!