2014-01-19 108 views
2

我使用Simple XML library连载一组元素:指定集合类型SimpleXML中的注释

@Root(name = "items") 
public class Items { 

    @ElementList(required = false, inline = true, entry = "item") 
    private Set<Item> items; 

    public Set<Item> getItems() { 
    return items; 
    } 

    public void setItems(final Set<Item> items) { 
    this.items = items; 
    } 
} 

我需要收集是一个Set,但同时也需要进行排序 - 此原因,当序列化时,我使用LinkedHashSet作为items的实际类型。

Set<Item> items = new LinkedHashSet<Item>(); 
items.add(...); 
items.add(...); 
items.add(...); 
Items root = new Items(); 
root.setItems(items); 
new Persister().write(root, stringWriter); 

这个工程只是罚款,所得XML包含在正确的顺序Item元素。

问题与反序列化 - 简单XML看到该类型是Set,挑选在CollectionFactory.getConversion()的实现:一个HashSet,不保留元素的顺序。

一个解决它的办法是改变Items定义:

@ElementList(required = false, inline = true, entry = "item") 
    private LinkedHashSet<Item> items; 

    public void setItems(final LinkedHashSet<Item> items) { 
    this.items = items; 
    } 

这工作,但它确实对良好的编码习惯。 有没有办法告诉Simple XML使用LinkedHashSet

+0

不错的问题,+1。 – ollo

回答

1

我猜这个问题是由内联引起的。如果你不使用inline,simple会将所有元素作为子元素放入set-tag中。该标签包含例如一个class="java.util.LinkedHashSet"属性,可以决定设置实现的是什么。

但是对于内联集合来说这是不可能的,所以简单的就需要一个默认的集合。

你可以做什么:

  1. 使用private LinkedHashSet<Item> items;因为你已经写 - 这让人很清楚自己想要什么样的实现
  2. 使用构造你实例化的实现:public Items() { this.items = new LinkedHashSet<>(); }
  3. Converter,你可以通过你自己来处理反序列化(可能是一种矫枉过正)。
+0

我真的不希望在我的XML API中实现特定于实现的属性 - 所以class =方法对我来说是不容置疑的。感谢其他人,但我一定会尝试一下。 – vektor

+0

我看到......在最糟糕的情况下,如果全部失败,您可以始终回退到Converter-implementation。 – ollo

+0

我刚刚找到时间来尝试解决方案2,它的工作原理!谢谢,接受! – vektor