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およびAddressクラスにequalsメソッドを実装する場合、実行時にメソッドの最後でそれらが等しいことを出力する必要があります。また、にいくつかの注釈を使用したことも注目に値しFamilyます。クラス自体で使用し、次に使用したオブジェクト@XStreamAlias("family")のコレクションで使用しました。Person@XStreamImplicit(itemFieldName="person")

そして、提供されたmainメソッドを実行したときの出力は次のとおりです。

<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 に答える