I am trying to deserialize an XML file to Java objects using simpleXML. Everything was working fine until I had to use an ElementMap. This is part of my XML file:

我试图使用simpleXML将XML文件反序列化为Java对象。一切都很好,直到我不得不使用ElementMap。这是我的XML文件的一部分:

<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>

The corresponding Java Class looks like this:

相应的Java类如下所示:

@Root
public class Piece {
    @Attribute
    private String composer;
    @Attribute
    private String title;
    @Attribute
    private String date;

    @ElementList
    private List<Edition> editions;

    @ElementMap(key = "id", attribute = true) // Relevant
    private Map<String, Layer> layers;        // Lines

    public static Piece loadFromAsset(Context context, String fileName) throws Exception {
        Serializer serial = new Persister();
        return serial.read(Piece.class, context.getResources().getAssets().open(fileName));
    }
}

And finally the Layer Class:

最后是Layer Class:

public class Layer {
    @Attribute
    private String id;
    @Attribute
    private String name;
    @Attribute
    private String description;
    @Attribute
    private String color;
}

After loading the XML file the Map contains both keys, but they both point to null instead of actual Layer Objects.

加载XML文件后,Map包含两个键,但它们都指向null而不是实际的Layer Objects。

1 个解决方案

#1


0

I am not SimpleFrawmerow user so I am not guarantee it will work but you should probably specify more attirbutes of ElementMap mappings:

我不是SimpleFrawmerow用户所以我不保证它会工作,但你应该指定更多的ElementMap映射的attirbutes:

@ElementMap(key = "id", attribute = true, keyType=String.class
            ,valueType=Layer.class)

If it does not help you have to handle list to map conversion yourself. The problem is that your xml holds actually a list of Layer elements instead of the map (there are no pairs of key /value elements).

如果它没有帮助你必须自己处理列表来映射转换。问题是你的xml实际上是一个Layer元素列表而不是map(没有键/值元素对)。

You can add to your Piece class extra field to store that list and have the map field constructed using it:

您可以添加Piece类额外字段来存储该列表,并使用它构建地图字段:

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;        
}

now there are two approaches:

现在有两种方法:

A) use getters and setters for layers list, and inside the methods construct the list map content as needed:

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) use the serialization life cycle mechanism (Persist and Commit annotations). In one method called before the serialization you create the list content using the map in the other you populate the map using the list values. I personally prefer it to getters/setters as you can hide the 'layers' element.

B)使用序列化生命周期机制(Persist和Commit annotations)。在序列化之前调用的一个方法中,使用另一个中的映射创建列表内容,使用列表值填充映射。我个人更喜欢它,因为你可以隐藏'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());
} 
} 

Finally you can use the Converter to control the process completely but I believe the above are easier and less verbose.

最后,你可以使用转换器完全控制过程,但我相信上面的内容更简单,更简洁。

更多相关文章

  1. 使用Java解析XML文件以获取名称列表
  2. Android-Dialog对话框 全解(普通对话框,单选对话框,多选对话框,列表
  3. 在android上滚动时,列表视图的位置会发生变化
  4. android 获取正在运行的应用程序列表
  5. 自定义BaseAdapter,在主Activity页面调用显示歌曲列表
  6. 按下子活动后退按钮后,Android主要活动的元素不响应
  7. Android:如何自动刷新UI上的元素(无需刷新整个屏幕)
  8. javascript实现设置select下拉列表框中选中内容。
  9. dom4j-java-如何获取root中具有特定元素名称的所有元素(父元素或

随机推荐

  1. android用okhttp和retrofit访问网络的时
  2. 转载:Android中针对怎么来使用
  3. AndroidX之CoordinatorLayout+AppBarLayo
  4. Android开发历程之三
  5. android的Handler
  6. 利用BLCR加速android的启动(android4.2)
  7. Android开发常用开源框架
  8. Android开发者指南(10) ―― Android API
  9. Android(安卓)WebRTC开发环境设置
  10. Android技术篇-了解Android的屏幕适配