将XML元素反序列化为Java映射
我正在尝试使用simpleXML将XML文件反序列化为Java对象。在我不得不使用元素地图之前,一切都很顺利。 这是我的XML文件的一部分:将XML元素反序列化为Java映射,java,android,xml,xml-deserialization,simple-framework,Java,Android,Xml,Xml Deserialization,Simple Framework,我正在尝试使用simpleXML将XML文件反序列化为Java对象。在我不得不使用元素地图之前,一切都很顺利。 这是我的XML文件的一部分: <piece composer="Me" date="Yesterday" title="Important work"> <editions> <edition name="My Name" date="2015" description="A single page">
<piece composer="Me" date="Yesterday" title="Important work">
<editions>
<edition name="My Name" date="2015" description="A single page">
<pages>
<page fileName="page01.jpg" />
</pages>
</edition>
<edition name="My Name again" date="2015" description="Another single page">
<pages>
<page fileName="page01.jpg" />
</pages>
</edition>
</editions>
<layers>
<layer name="Annotations" color="#FF0000" description="Empty" id="anno" />
<layer name="Information" color="#00FF00" description="Empty" id="info" />
</layers>
</piece>
加载XML文件后,映射包含两个键,但它们都指向null,而不是实际的层对象。我不是SimpleFrawmerow用户,因此我不能保证它会工作,但您可能应该指定更多ElementMap映射的attirbutes:
@ElementMap(key = "id", attribute = true, keyType=String.class
,valueType=Layer.class)
若并没有帮助,你们必须自己处理从列表到映射的转换。问题是,xml实际上包含一个层元素列表,而不是映射。没有键/值元素对
您可以将额外字段添加到工件类中以存储该列表,并使用该列表构建地图字段:
class Piece {
...
@ElementList //only for solution B, for a do not use this annotation
List<Layer> layers;
@Transient //importatnt as it does not go into xml directly
private Map<String, Layer> layersMap;
}
现在有两种方法:
A使用层列表的getter和setter,并在方法内部根据需要构造列表映射内容:
@ElementList
public void setLayers(Collection<Layer> layers) {
layersMap = new HashMap<>();
for (Layer l : layers) layersMap.put(l.getId(),l);
}
@ElementList
public Collection<Layer> getLayers() {
return layersMap.values();
}
B使用序列化生命周期机制持久化和提交注释。在序列化之前调用的一个方法中,使用映射创建列表内容;在另一个方法中,使用列表值填充映射。我个人更喜欢它而不是getter/setter,因为您可以隐藏“layers”元素
class Piece {
....
@Commit
public void prepareMap() {
layersMap = new HashMap<>();
for (Layer l : layers) layersMap.put(l.getId(),l);
}
@Persist
public void prepareList() {
layers = new ArrayList<>();
layers.addAll(layersMap.values());
}
}
最后,您可以使用转换器完全控制流程,但我相信上面的内容更简单,更不冗长。非常感谢!我最终使用了与您的方法A几乎完全相同的语法。其他的解决方案也同样有效,但简单却很漂亮-
@ElementList
public void setLayers(Collection<Layer> layers) {
layersMap = new HashMap<>();
for (Layer l : layers) layersMap.put(l.getId(),l);
}
@ElementList
public Collection<Layer> getLayers() {
return layersMap.values();
}
class Piece {
....
@Commit
public void prepareMap() {
layersMap = new HashMap<>();
for (Layer l : layers) layersMap.put(l.getId(),l);
}
@Persist
public void prepareList() {
layers = new ArrayList<>();
layers.addAll(layersMap.values());
}
}