Java JDOM2 – Read XML Example

JDOM parser can be used to read XML, parse xml and write XML file after updating content of it. It stores JDOM2 document in memory to read and modify it’s values.

After loading 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.

Table of Contents

Project Structure
JDOM2 Maven Dependency
Create JDOM2 Document
Read and filter XML content
Read XML Content with XPath
Complete Example
Sourcecode Download

Project Structure

Please create this folder structure to execute the examples. It is a simple maven project created in eclipse.

JDOM2 XML Parser
Project Structure

Please note that I have used lambda expressions and method references, so you will need to configure to project to use JDK 1.8.

JDOM2 Maven Dependency

<dependency>
	<groupId>org.jdom</groupId>
	<artifactId>jdom2</artifactId>
	<version>2.0.6</version>
</dependency>

To execute XPaths, you will need jaxen as well.

<dependency>
	<groupId>jaxen</groupId>
	<artifactId>jaxen</artifactId>
	<version>1.1.6</version>
</dependency>

Create JDOM2 Document

You can create org.jdom2.Document instance using any parser listed down below. They all parse the XML and return in-memory JDOM document.

  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. 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;
    }
    
  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;
    }
    

Read and filter XML content

I will be reading 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>

Read root node

Use document.getRootElement() method.

public static void main(String[] args) 
{
	String xmlFile = "employees.xml";
	Document document = getSAXParsedDocument(xmlFile);

	Element rootNode = document.getRootElement();
	System.out.println("Root Element :: " + rootNode.getName());
}

Output:

Root Element :: employees

Read 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"));
}

Output:

Id : 101
Id : 102

Read 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"));
}

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

Read XML Content with XPath

To read any set of element’s value using xpath, You 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());
}

Output:

Employee Ids :: 101
Employee Ids :: 102

Employee First Name :: Lokesh
Employee First Name :: Brian

Complete JDOM2 Read XML Example

Here is complete code to read xml using JDOM2 in java.

package com.howtodoinjava.demo.jdom2;

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();
	}*/
}

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

Sourcecode Download

Happy Learning !!

References:

JDOM Website
JDOM2 Primer

Was this post helpful?

Join 7000+ Fellow Programmers

Subscribe to get new post notifications, industry updates, best practices, and much more. Directly into your inbox, for free.

Leave a Comment

HowToDoInJava

A blog about Java and its related technologies, the best practices, algorithms, interview questions, scripting languages, and Python.