Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XStream Implicit Collection Configuration Issue

Tags:

java

xml

xstream

I'm working with a system that generates this type of XML:

<address>
  <addressLine>123 Main Street</addressLine>
  <addressLine>Suite 123</addressLine>
  <city>Test City</city>
  <stateOrProvince>AA</stateOrProvince>
  <postalCode>00000</postalCode>
</address>

The two addressLine elements should be part of an XStream implicit collection - I'd like to call a getAddressLine() method and get a List<String> output.

I've been working with XStream's tutorial and haven't quite figured out how to get the addressLine elements to map correctly. There's a similar use case in XStream's Tweaking Output tutorial, but no example code is provided:

Another use case are collections, arrays and maps. If a class has a field that is a one of those types, by default all of its elements are embedded in an element that represents the container object itself. By configuring the XStream with the XStream.addImplicitCollection(), XStream.addImplicitArray(), and XStream.addImplicitMap() methods it is possible to keep the elements directly as child of the class and the surrounding tag for the container object is omitted. It is even possible to declare more than one implicit collection, array or map for a class, but the elements must then be distinguishable to populate the different containers correctly at deserialization.

In the following example the Java type representing the farm may have two containers, one for cats and one for dogs:

<farm>
  <cat>Garfield</cat>
  <cat>Arlene</cat>
  <cat>Nermal</cat>
  <dog>Odie</dog>
</farm>

However, this SO answer suggests that the XStream farm example is not possible.

I've tried this Java code to unit test my Java code, but no luck yet:

XStream xstream = new XStream(new StaxDriver());        
xstream.alias("address", Address.class);
xstream.alias("addressLine", String.class);     
xstream.addImplicitCollection(Address.class, "addressLines");       

Address address = (Address) xstream.fromXML( 
    new FileInputStream("src/test/resources/addressTest.xml"));

Are there any other configuration changes I should try?

Note: I'm currently using XStream v1.2.2.

like image 681
JW8 Avatar asked Dec 20 '22 15:12

JW8


1 Answers

First, if possible you should upgrade to a more recent XStream - 1.2.2 was released in 2007. But to answer your question, try:

XStream xstream = new XStream(new StaxDriver());
xstream.alias("address", Address.class);
xstream.addImplicitCollection(Address.class, "addressLines", "addressLine", String.class);

This says treat all elements with the name addressLine as Strings, and gather them into the addressLines collection (i.e. someAddress.getAddressLines()).

like image 63
Ian Roberts Avatar answered Dec 24 '22 00:12

Ian Roberts