Search code examples
xmllistreferencexstream

How to reference two lists each other in XStream?


I have to make a reference between elements of two lists. I have tried using XStream. Here is example of XML:

<bookshop>
    <authors>
        <author id="a1">
            <name>Stanisław</name>
        </author>
    </authors>
    <books>
        <book id="b1">
            <author>a1</author>
            <title>Ubik</title>
            <price currency="PLN">29.0</price>
        </book>
    </books>
</bookshop>

and some scratches of my Java classes:

public class Bookshop {
    private ArrayList<Author> authors;
    private ArrayList<Book> boooks;
}

public class Book {
    @XStreamAsAttribute
    private String id;
    private Author author;
    private String title;
    private Price price;
}

@XStreamConverter(value=ToAttributedValueConverter.class, strings={"value"})
public class Price {
    private double value;
    @XStreamAsAttribute
    private String currency;
}

public class Author {
    @XStreamAsAttribute
    private String id;
    private String name;
    private String surname;
}

And everytime when i'm trying to put xml into classes i get nulls in Author autor field. Maybe i need some more annotation but i have not found anything in Xstream docs.


Solution

  • Your XML is wrong. Here is what XStream gives if you try to serialize an instance of Bookshop:

    <bookshop>
      <authors>
        <author>
          <id>a1</id>
          <name>Yuri</name>
          <surname>Stanislaw</surname>
        </author>
        <author>
          <id>a2</id>
          <name>Bill</name>
          <surname>Gates</surname>
        </author>
      </authors>
      <books>
        <book>
          <id>b1</id>
          <author reference="/bookshop/authors/author[2]"/>
          <title>Programming basics</title>
          <price>
            <currency>USD</currency>
            <value>100.0</value>
          </price>
        </book>
      </books>
    </bookshop>
    

    The XML above is serialized with the following settings:

    xstream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);
    xstream.alias("bookshop", Bookshop.class);
    xstream.alias("author", Author.class);
    xstream.alias("book", Book.class);
    

    The complete source code I used for testing can be found here

    If this isn't a sufficient solution for the reference problem, I would suggest writing your own Converter to use with XStream, a short tutorial can be found here