I usually post about Dev stuff on Twitter - you can follow me there:
Follow @baeldung1. Overview
In a previous article, we learned how to use XStream to serialize Java objects to XML. In this tutorial, we will learn how to do the reverse: deserialize XML to Java objects. These tasks can be accomplished using annotations or programmatically.
To learn about the basic requirements for setting up XStream and its dependencies, please reference the previous article.
2. Deserialize an Object from XML
To start with, suppose we have the following XML:
<com.baeldung.pojo.Customer> <firstName>John</firstName> <lastName>Doe</lastName> <dob>1986-02-14 03:46:16.381 UTC</dob> </com.baeldung.pojo.Customer>
We need to convert this to a Java Customer object:
public class Customer { private String firstName; private String lastName; private Date dob; // standard setters and getters }
The XML can be input in a number of ways, including File, InputStream, Reader, or String. For simplicity, we’ll assume that we have the XML above in a String object.
Customer convertedCustomer = (Customer) xstream.fromXML(customerXmlString); Assert.assertTrue(convertedCustomer.getFirstName().equals("John"));
3. Aliases
In the first example, the XML had the fully-qualified name of the class in the outermost XML tag, matching the location of our Customer class. With this setup, XStream easily converts the XML to our object without any extra configuration. But we may not always have these conditions. We might not have control over the XML tag naming, or we might decide to add aliases for fields.
For example, suppose we modified our XML to not use the fully-qualified class name for the outer tag:
<customer> <firstName>John</firstName> <lastName>Doe</lastName> <dob>1986-02-14 03:46:16.381 UTC</dob> </customer>
We can covert this XML by creating aliases.
3.1. Class Aliases
We register aliases with the XStream instance either programmatically or using annotations. We can annotate our Customer class with @XStreamAlias:
@XStreamAlias("customer") public class Customer { //... }
Now we need to configure our XStream instance to use this annotation:
xstream.processAnnotations(Customer.class);
Alternatively, if we wish to configure an alias programmatically, we can use the code below:
xstream.alias("customer", Customer.class);
3.2. Field Aliases
Suppose we have the following XML:
<customer> <fn>John</fn> <lastName>Doe</lastName> <dob>1986-02-14 03:46:16.381 UTC</dob> </customer>
The fn tag doesn’t match any fields in our Customer object, so we will need to define an alias for that field if we wish to deserialize it. We can achieve this using the following annotation:
@XStreamAlias("fn") private String firstName;
Alternatively, we can accomplish the same goal programmatically:
xstream.aliasField("fn", Customer.class, "firstName");
4. Implicit Collections
Let’s say we have the following XML, containing a simple list of ContactDetails:
<customer> <firstName>John</firstName> <lastName>Doe</lastName> <dob>1986-02-14 04:14:20.541 UTC</dob> <ContactDetails> <mobile>6673543265</mobile> <landline>0124-2460311</landline> </ContactDetails> <ContactDetails>...</ContactDetails> </customer>
We want to load the list of ContactDetails into a List<ContactDetails> field in our Java object. We can achieve this by using the following annotation:
@XStreamImplicit private List<ContactDetails> contactDetailsList;
Alternatively, we can accomplish the same goal programmatically:
xstream.addImplicitCollection(Customer.class, "contactDetailsList");
5. Ignore Fields
Let’s say we have following XML:
<customer> <firstName>John</firstName> <lastName>Doe</lastName> <dob>1986-02-14 04:14:20.541 UTC</dob> <fullName>John Doe</fullName> </customer>
In the XML above, we have extra element <fullName> which is missing from our Java Customer object.
If we try to deserialize the above xml without taking any care for extra element, program throws an UnknownFieldException.
No such field com.baeldung.pojo.Customer.fullName
As the exception clearly states, XStream does not recognize the field fullName.
To overcome this problem we need to configure it to ignore unknown elements:
xstream.ignoreUnknownElements();
6. Attribute Fields
Suppose we have XML with attributes as part of elements that we’d like to deserialize as a field in our object. We will add a contactType attribute to our ContactDetails object:
<ContactDetails contactType="Office"> <mobile>6673543265</mobile> <landline>0124-2460311</landline> </ContactDetails>
If we want to deserialize the contactType XML attribute, we can use the @XStreamAsAttribute annotation on the field we’d like it to appear in:
@XStreamAsAttribute private String contactType;
Alternatively, we can accomplish the same goal programmatically:
xstream.useAttributeFor(ContactDetails.class, "contactType");
7. Conclusion
In this article, we explored the options we have available when deserializing XML to Java objects using XStream.
The complete source code for this article can be downloaded from the linked GitHub repository.