Xstream does not maintain order of child elements while unmarshalling

一笑奈何 提交于 2019-12-11 21:47:21

问题


How maintain the order of unmarshalled child objects in a Set. Below is my xml, when converting to java objects order that I get in set is not A,B,C. How can I achieve that?

<company id="abc">
  <emp name="A"/>
  <emp name="B"/>
  <emp name="C"/>
</company>

Edit: Observations:

  1. In my Company.class I had defined Set<Employee> and when xstream unmarshall it, it create the set as HashMap, so the order is not maintained. Ques) How can I use LinkedHashMap in xstream to maintain the order?

  2. Then I defined the employee set as LinkedHashSet<Employee>. Doing this xstream create set as LinkedHashMap and order is maintained but Hibernate throws exception because there I have defined Set <set name="employees"> and it throws error on casting Set to LinkedHashSet

public void setEmployees(Set<Employee> emps){
  this.packages = (LinkedHashSet<Employee>)emps;
}

回答1:


Set is not ordered. If you like deifnite order, use list. This has nothing with xstream.




回答2:


I believe you are looking for ordering based on the content and not the order in which the emp element occurs in the XML instance. If this is the case then SortedSet can maintain natural ordering. But not sure how xstream unmarshalls it though. If there is a way to map it to SortedSet then you achieve what you are looking for.

If you want the data ordered by their occurence in XML instance then you could ask xtream to map it to List implementations but I am not sure xstream guarantees this behavior.

If order is important then my suggestion is to make it explicitly part of the contract by adding an order or index attribute to emp element.




回答3:


I solved the problem using my custom Converter but I guess there has to be a better way that to used custom converter for such a small problem. I'll keep looking but until then.

Add this

xstream.registerConverter(new CompanyConverter());

public Object unmarshal(HierarchicalStreamReader reader,UnmarshallingContext context) {

        Company comp = new Company();


        Set<Employee> packages = new LinkedHashSet<Employee>();

        while(reader.hasMoreChildren()){
            reader.moveDown();
            if("emp".equals(reader.getNodeName())){
                Employee emp = (Employee)context.convertAnother(comp, Employee.class);
                employees.add(emp);
            }
            reader.moveUp();
        }
        comp.setEmployees(employees);
        return comp;
    }


来源:https://stackoverflow.com/questions/9097017/xstream-does-not-maintain-order-of-child-elements-while-unmarshalling

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!