Parsing XML Files with JAXB

– Requires Java ≥ 1.6

JAXB API (included in the standard Java distribution since 1.6) allows to marshall/unmarshall XML files using annotations very easily.

Using only a couple of JAXB annotations, one can parse XML files. In this post, I used a restricted set of JAXB annotations, but this is more than sufficient to load such XML files.

Please refer to the Java JAXB documentation if you want to know more about these annotations (and others) and the way one can configure them.

Let’s dive directly into code. We are interested in parsing the following XML file (the complete source code is available here).

person.xml
<?xml version="1.0" encoding="UTF-8"?>
<person>
	<civility>
		<lastname>ICHIR</lastname>
		<firstname>Mahieddine M.</firstname>
	</civility>
	<birthDate>24/10/1978</birthDate>
	<sex />
	<parents>
		<father>
			<birthDate>21/12/1933</birthDate>
			<civility>
				<lastname>ICHIR</lastname>
				<firstname>IXXX</firstname>
			</civility>
		</father>
		<mother>
			<birthDate>12/08/1952</birthDate>
			<civility>
				<lastname>OUYYY</lastname>
				<firstname>FeYYY</firstname>
			</civility>
		</mother>
	</parents>
</person>
The “main” class entry point (MyMain.java)

This is the entry point of our Java program: it loads the XML file content and initializes the JAXB parser.

public static void main(String[] args) throws JAXBException {
	InputStream is = MyMain.class.getResourceAsStream("/person.xml");
	XmlLoader loader = new XmlLoader();
	loader.parse(is);
	Person person = loader.getPerson();
	System.out.println(person);
}
JaxB XML Parser (XmlParser.java)

This is where we initialize the JAXB parser (we get a new instance of it) and where we ask JAXB to do the “hassling” job for us (once we have correctly annotated our classes).

	...
	public void parse(InputStream is) throws JAXBException {
		JAXBContext context = JAXBContext.newInstance(Person.class);
		Unmarshaller unmarshaller = context.createUnmarshaller();
		person = (Person) unmarshaller.unmarshal(is);
	}
	...
(XML) Mapping Beans
The root XML element: Person.java

This is the “Person” bean class that JAXB will map to the “<person>” root XML element.

package com.ichir.projects.beans;

import java.util.Date;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import com.ichir.projects.jaxb.DateAdapter;

@XmlRootElement(name="person")
@XmlAccessorType(XmlAccessType.FIELD)
public class Person {

	@XmlElement(name="civility")
	private Civility civility;
	
	@XmlElement(name="sex", defaultValue="M")
	private Sex sex;

	@XmlElement(name="birthDate")
	@XmlJavaTypeAdapter(DateAdapter.class)
	private Date birth;

	@XmlElement
	private Parents parents;
	...
	// getters and setters
An XML Tag element: Civility.java

This is one of the XML attributes of the “<person>” root element, the “<civility>” XML tag/element.

package com.ichir.projects.beans;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="civility")
@XmlAccessorType(XmlAccessType.FIELD)
public class Civility {

	@XmlElement
	private String lastname;
	
	@XmlElement(name="firstname")
	private String firstname;
	...
	// setters and getters
}
An enum type: Sex.java

An “Enum” type is used for the “<sex>” XML tag to highlight how JAXB is able to handle enumerations.

package com.ichir.projects.beans;

import javax.xml.bind.annotation.XmlEnum;
@XmlEnum
public enum Sex {
	M,
	W
}
Xml Adapters: DateAdapter.java

A “dateTime” format for the date of birth XML tag in required! So we used the JaxB “XMLAdapter” in order to highlight how JAXB handles such “complex” mappings. See also the “Person.java” class, and especially the @XmlJavaTypeAdapter annotation for the birth class attribute.

package com.ichir.projects.jaxb;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.xml.bind.annotation.adapters.XmlAdapter;

public class DateAdapter extends XmlAdapter<String, Date> {

	private DateFormat format = new SimpleDateFormat("dd/MM/yyyy");
	
	@Override
	public Date unmarshal(String v) throws Exception {
		return format.parse(v);
	}
	@Override
	public String marshal(Date v) throws Exception {
		return format.format(v);
	}
}
downloads
references
Advertisements