Search code examples
javaxstream

XStream.fromXML List producing empty list


I'm trying to learn XStream, and I've followed the API as well as I can understand it, but the following code snippet

List<Rectangle> rectangleArray = new ArrayList<Rectangle>();
xstream = new XStream(new DomDriver());
List<Rectangle> rectangleArray2 = new ArrayList<Rectangle>();

rectangleArray.add(new Rectangle(18,45,2,6));
String xml = xstream.toXML(rectangleArray);
System.out.println(xml);
xstream.fromXML(xml, rectangleArray2);
System.out.println("new list size: " + rectangleArray2.size());

produces output

<list>
    <java.awt.Rectangle>
    <x>18</x>
    <y>45</y>
    <width>2</width>
    <height>6</height>
    </java.awt.Rectangle>
</list>
new list size: 0

and I cannot figure out why rectangleArray2 is not now a copy of rectangleArray. Any help?


Solution

  • Handling List through XStream is bit trickier. To handle the list, you need to define a wrapper class to hold your list e.g.:

        public class RectangleList {
    
            private List<Rectangle> rectangles = new ArrayList<Rectangle>();
    
            public List<Rectangle> getRectangles() {
                return rectangles;
            }
    
            public void setRectangles(List<Rectangle> rectangles) {
                this.rectangles = rectangles;
            }
        }
    

    Then add alias for list to RectangleList class as

          xstream.alias("list", RectangleList.class);
    

    and register an implicit converter to manage the list as:

         xstream.addImplicitCollection(RectangleList.class, "rectangles"); 
    

    If you want your <java.awt.Rectangle> to print as <rectangle>, register ans alias as below:

         xstream.alias("rectangle", Rectangle.class);
    

    Now use you RectangleList class for conversion, it should work fine.

    Final test code will look like:

        RectangleList recListInput = new RectangleList();
        RectangleList recListOutput = new RectangleList();
        XStream xstream = new XStream(new DomDriver());
        xstream.alias("list", RectangleList.class);
        xstream.alias("rectangle", Rectangle.class);
        xstream.addImplicitCollection(RectangleList.class, "rectangles");
    
        ArrayList<Rectangle> rectangleArray = new ArrayList<Rectangle>();
        rectangleArray.add(new Rectangle(18,45,2,6));
        recListInput.setRectangles(rectangleArray);
        String xml = xstream.toXML(rectangleArray);
        System.out.println(xml);
        xstream.fromXML(xml, recListOutput);
        System.out.println("new list size: " + recListOutput.getRectangles().size());
    

    This will print output as:

        <list>
          <rectangle>
            <x>18</x>
            <y>45</y>
            <width>2</width>
            <height>6</height>
          </rectangle>
        </list>
        new list size: 1