1

这是场景:

<family>
    <person>name</person>
    <person>
        <address> street </adress>
        <address> street </address>
    </person>
</family>

person 值可以是地址列表或只是人名。我认为解决方案是使用转换器,但你是怎么做到的?

  1. 检查您检索的输入?
  2. 告诉转换器继续使用 3 类的默认值?

示例类:(请注意,这是为了说明)

public class Person {

    private String name;

    private List<Address> address;
}

public class Address {
    private String street;    
}
4

1 回答 1

2

您确实需要使用转换器。这是您的示例的转换器:

public class PersonConverter implements Converter {

    public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) {
        Person person = (Person) value;
        if(person.name != null){
            writer.setValue(person.name);
        } else if(person.address != null){
            for (Address address : person.address){
                writer.startNode("address");
                writer.setValue(address.street);
                writer.endNode();
            }
        }


    }

    public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
        Person person = new Person();
        person.name = reader.getValue();
        if(person.name.trim().length()==0){
            person.name = null;
        }
        List<Address> addresses = getAddress(reader, new ArrayList<Address>());
        person.address = addresses;
        if(person.address.size() == 0){
            person.address = null;
        }
        return person;
    }

    private List<Address> getAddress(HierarchicalStreamReader reader, List<Address> addresses){
        if (!reader.hasMoreChildren()){
            return addresses;
        }
        reader.moveDown();
        if(reader.getNodeName().equals("address")){
            addresses.add(new Address(reader.getValue()));
            reader.moveUp();
            getAddress(reader, addresses);
        }
        return addresses;
    }

    public boolean canConvert(Class clazz) {
        return clazz.equals(Person.class);
    }
}

下面是主要方法:

public static void main(String[] args) {        
    List<Person> persons = new ArrayList<Person>();
    persons.add(new Person("John"));

    List<Address> adds = new ArrayList<Address>();
    adds.add(new Address("123 street"));
    adds.add(new Address("456 street"));

    persons.add(new Person(adds));

    Family family = new Family(persons);


    XStream stream = new XStream();     
    stream.registerConverter(new PersonConverter());
    stream.processAnnotations(new Class[]{Family.class});

    String xml = stream.toXML(family);
    System.out.println(xml);

    Family testFam = (Family) stream.fromXML(xml);
    System.out.println("family.equals(testFam) => "+family.equals(testFam));

}

Family如果您为、Person和类实现 equals 方法,Address它应该在运行时在方法末尾打印它们相等。另外值得注意的是,我在Family. 我@XStreamAlias("family")在 Class 本身上使用过,然后在Person我使用的对象集合上使用过@XStreamImplicit(itemFieldName="person")

这是我运行提供的主要方法时的输出:

<family>
  <person>John</person>
  <person>
    <address>123 street</address>
    <address>456 street</address>
  </person>
</family>
family.equals(testFam) => true
于 2012-11-15T21:50:17.863 回答