JDOM2 parser can be used to read XML, parse XML and write XML files after updating the content of it. It stores the JDOM2 documents in memory to read and modify their values. After loading the XML document into memory, JDOM2 maintains a strict parent-child type relationship. Parent-type JDOM instances (parent) have methods to access their content, and child-type JDOM instances (content) have methods to access their parent.
Please note that we have used lambda expressions and method references in this tutorial, so we must configure to project to use minimum Java version 1.8.
1. Maven
Include the latest version of jdom2 in the project.
<dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom2</artifactId>
<version>2.0.6.1</version>
</dependency>
To execute XPaths, we will need jaxen as well.
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>2.0.0</version>
</dependency>
2. Create JDOM2 Document
We can create org.jdom2.Document
instance using any parser listed down below. They all parse the XML and return in-memory JDOM2 document.
2.1. Using DOM Parser
private static Document getDOMParsedDocument(final String fileName) {
Document document = null;
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//If want to make namespace aware.
//factory.setNamespaceAware(true);
DocumentBuilder documentBuilder = factory.newDocumentBuilder();
org.w3c.dom.Document w3cDocument = documentBuilder.parse(fileName);
document = new DOMBuilder().build(w3cDocument);
}
catch (IOException | SAXException | ParserConfigurationException e) {
e.printStackTrace();
}
return document;
}
2.2. Using SAX Parser
private static Document getSAXParsedDocument(final String fileName) {
SAXBuilder builder = new SAXBuilder();
Document document = null;
try {
document = builder.build(fileName);
}
catch (JDOMException | IOException e) {
e.printStackTrace();
}
return document;
}
2.3. Using StAX Parser
private static Document getStAXParsedDocument(final String fileName) {
Document document = null;
try {
XMLInputFactory factory = XMLInputFactory.newFactory();
XMLEventReader reader = factory.createXMLEventReader(new FileReader(fileName));
StAXEventBuilder builder = new StAXEventBuilder();
document = builder.build(reader);
}
catch (JDOMException | IOException | XMLStreamException e) {
e.printStackTrace();
}
return document;
}
3. Reading XML Content
We will be reading the following employees.xml
file.
<employees>
<employee id="101">
<firstName>Lokesh</firstName>
<lastName>Gupta</lastName>
<country>India</country>
<department id="25">
<name>ITS</name>
</department>
</employee>
<employee id="102">
<firstName>Brian</firstName>
<lastName>Schultz</lastName>
<country>USA</country>
<department id="26">
<name>DEV</name>
</department>
</employee>
</employees>
3.1. Root Node
Use document.getRootElement()
method.
String xmlFile = "employees.xml";
Document document = getSAXParsedDocument(xmlFile);
Element rootNode = document.getRootElement();
System.out.println("Root Element :: " + rootNode.getName());
Program output:
Root Element :: employees
3.2. Attribute Value
Use Element.getAttributeValue() method.
public static void main(String[] args) {
String xmlFile = "employees.xml";
Document document = getSAXParsedDocument(xmlFile);
Element rootNode = document.getRootElement();
rootNode.getChildren("employee").forEach( ReadXMLDemo::readEmployeeNode );
}
private static void readEmployeeNode(Element employeeNode) {
//Employee Id
System.out.println("Id : " + employeeNode.getAttributeValue("id"));
}
Program output:
Id : 101
Id : 102
3.3. Element Value
Use Element.getChildText()
or Element.getText()
methods.
public static void main(String[] args) {
String xmlFile = "employees.xml";
Document document = getSAXParsedDocument(xmlFile);
Element rootNode = document.getRootElement();
rootNode.getChildren("employee").forEach( ReadXMLDemo::readEmployeeNode );
}
private static void readEmployeeNode(Element employeeNode) {
//Employee Id
System.out.println("Id : " + employeeNode.getAttributeValue("id"));
//First Name
System.out.println("FirstName : " + employeeNode.getChildText("firstName"));
//Last Name
System.out.println("LastName : " + employeeNode.getChildText("lastName"));
//Country
System.out.println("country : " + employeeNode.getChild("country").getText());
/**Read Department Content*/
employeeNode.getChildren("department").forEach( ReadXMLDemo::readDepartmentNode );
}
private static void readDepartmentNode(Element deptNode) {
//Department Id
System.out.println("Department Id : " + deptNode.getAttributeValue("id"));
//Department Name
System.out.println("Department Name : " + deptNode.getChildText("name"));
}
Program output:
FirstName : Lokesh
LastName : Gupta
country : India
Department Id : 25
Department Name : ITS
FirstName : Brian
LastName : Schultz
country : USA
Department Id : 26
Department Name : DEV
4. Using XPath
To read any set of element’s values using xpath, we need to compile XPathExpression
and use it’s evaluate()
method.
String xmlFile = "employees.xml";
Document document = getSAXParsedDocument(xmlFile);
XPathFactory xpfac = XPathFactory.instance();
//Read employee ids
XPathExpression<Attribute> xPathA = xpfac.compile("//employees/employee/@id", Filters.attribute());
for (Attribute att : xPathA.evaluate(document)) {
System.out.println("Employee Ids :: " + att.getValue());
}
//Read employee first names
XPathExpression<Element> xPathN = xpfac.compile("//employees/employee/firstName", Filters.element());
for (Element element : xPathN.evaluate(document)) {
System.out.println("Employee First Name :: " + element.getValue());
}
Program output:
Employee Ids :: 101
Employee Ids :: 102
Employee First Name :: Lokesh
Employee First Name :: Brian
5. Complete Example
Here is the complete code to read XML using JDOM2 in java.
import java.io.FileReader;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.filter.Filters;
import org.jdom2.input.DOMBuilder;
import org.jdom2.input.SAXBuilder;
import org.jdom2.input.StAXEventBuilder;
import org.jdom2.xpath.XPathExpression;
import org.jdom2.xpath.XPathFactory;
import org.xml.sax.SAXException;
@SuppressWarnings("unused")
public class ReadXMLDemo
{
public static void main(String[] args)
{
String xmlFile = "employees.xml";
Document document = getSAXParsedDocument(xmlFile);
/**Read Document Content*/
Element rootNode = document.getRootElement();
System.out.println("Root Element :: " + rootNode.getName());
System.out.println("\n=================================\n");
/**Read Employee Content*/
rootNode.getChildren("employee").forEach( ReadXMLDemo::readEmployeeNode );
System.out.println("\n=================================\n");
readByXPath(document);
}
private static void readEmployeeNode(Element employeeNode)
{
//Employee Id
System.out.println("Id : " + employeeNode.getAttributeValue("id"));
//First Name
System.out.println("FirstName : " + employeeNode.getChildText("firstName"));
//Last Name
System.out.println("LastName : " + employeeNode.getChildText("lastName"));
//Country
System.out.println("country : " + employeeNode.getChild("country").getText());
/**Read Department Content*/
employeeNode.getChildren("department").forEach( ReadXMLDemo::readDepartmentNode );
}
private static void readDepartmentNode(Element deptNode)
{
//Department Id
System.out.println("Department Id : " + deptNode.getAttributeValue("id"));
//Department Name
System.out.println("Department Name : " + deptNode.getChildText("name"));
}
private static void readByXPath(Document document)
{
//Read employee ids
XPathFactory xpfac = XPathFactory.instance();
XPathExpression<Attribute> xPathA = xpfac.compile("//employees/employee/@id", Filters.attribute());
for (Attribute att : xPathA.evaluate(document))
{
System.out.println("Employee Ids :: " + att.getValue());
}
XPathExpression<Element> xPathN = xpfac.compile("//employees/employee/firstName", Filters.element());
for (Element element : xPathN.evaluate(document))
{
System.out.println("Employee First Name :: " + element.getValue());
}
}
private static Document getSAXParsedDocument(final String fileName)
{
SAXBuilder builder = new SAXBuilder();
Document document = null;
try
{
document = builder.build(fileName);
}
catch (JDOMException | IOException e)
{
e.printStackTrace();
}
return document;
}
private static Document getStAXParsedDocument(final String fileName)
{
Document document = null;
try
{
XMLInputFactory factory = XMLInputFactory.newFactory();
XMLEventReader reader = factory.createXMLEventReader(new FileReader(fileName));
StAXEventBuilder builder = new StAXEventBuilder();
document = builder.build(reader);
}
catch (JDOMException | IOException | XMLStreamException e)
{
e.printStackTrace();
}
return document;
}
private static Document getDOMParsedDocument(final String fileName)
{
Document document = null;
try
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//If want to make namespace aware.
//factory.setNamespaceAware(true);
DocumentBuilder documentBuilder = factory.newDocumentBuilder();
org.w3c.dom.Document w3cDocument = documentBuilder.parse(fileName);
document = new DOMBuilder().build(w3cDocument);
}
catch (IOException | SAXException | ParserConfigurationException e)
{
e.printStackTrace();
}
return document;
}
/*private static String readFileContent(String filePath)
{
StringBuilder contentBuilder = new StringBuilder();
try (Stream<String> stream = Files.lines( Paths.get(filePath), StandardCharsets.UTF_8))
{
stream.forEach(s -> contentBuilder.append(s).append("\n"));
}
catch (IOException e)
{
e.printStackTrace();
}
return contentBuilder.toString();
}*/
}
Program output:
Root Element :: employees
=================================
Id : 101
FirstName : Lokesh
LastName : Gupta
country : India
Department Id : 25
Department Name : ITS
Id : 102
FirstName : Brian
LastName : Schultz
country : USA
Department Id : 26
Department Name : DEV
=================================
Employee Ids :: 101
Employee Ids :: 102
Employee First Name :: Lokesh
Employee First Name :: Brian
Happy Learning !!
Leave a Reply