Find xml element with attribute value using xpath in Java

Simple example for how to get attribute value in xml using xpath in Java. We will learn to fetch information for matching attribute values, attribute values in range, xpath attribute contains() and so on.

1. XPath attribute expressions

1.1. Input XML file

First look at the XML file which we will read and then fetch information from it, using xpath queries.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<employees>
    <employee id="1">
        <firstName>Lokesh</firstName>
        <lastName>Gupta</lastName>
        <department>
            <id>101</id>
            <name>IT</name>
        </department>
    </employee>
    <employee id="2">
        <firstName>Brian</firstName>
        <lastName>Schultz</lastName>
        <department>
            <id>102</id>
            <name>HR</name>
        </department>
    </employee>
    <employee id="3">
        <firstName>Alex</firstName>
        <lastName>Kolenchisky</lastName>
        <department>
            <id>103</id>
            <name>FINANCE</name>
        </department>
    </employee>
    <employee id="4">
        <firstName>Amit</firstName>
        <lastName>Jain</lastName>
        <department>
            <id>104</id>
            <name>HR</name>
        </department>
    </employee>
    <employee id="5">
        <firstName>David</firstName>
        <lastName>Beckham</lastName>
        <department>
            <id>105</id>
            <name>DEVOPS</name>
        </department>
    </employee>
    <employee id="6">
        <firstName>Virat</firstName>
        <lastName>Kohli</lastName>
        <department>
            <id>106</id>
            <name>DEVOPS</name>
        </department>
    </employee>
    <employee id="7">
        <firstName>John</firstName>
        <lastName>Wick</lastName>
        <department>
            <id>107</id>
            <name>IT</name>
        </department>
    </employee>
    <employee id="8">
        <firstName>Mike</firstName>
        <lastName>Anderson</lastName>
        <department>
            <id>108</id>
            <name>HR</name>
        </department>
    </employee>
    <employee id="9">
        <firstName>Bob</firstName>
        <lastName>Sponge</lastName>
        <department>
            <id>109</id>
            <name>FINANCE</name>
        </department>
    </employee>
    <employee id="10">
        <firstName>Gary</firstName>
        <lastName>Kasporov</lastName>
        <department>
            <id>110</id>
            <name>IT</name>
        </department>
    </employee>
</employees>

1.2. XPath attribute expressions example

Now see few examples of how to build xpath for getting information based on attributes.

DescriptionXPathResult
Get all employee ids/employees/employee/@id[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Get all employee ids in HR department/employees/employee[department/name='HR']/@id[2, 4, 8]
Get employee id of ‘Alex’/employees/employee[firstName='Alex']/@id[3]
Get employee ids greater than 5/employees/employee/@id[. > 5][6, 7, 8, 9, 10]
Get employee whose id contains ‘1’/employees/employee[contains(@id,'1')]/firstName/text()[Lokesh, Gary]
Get employee whose id contains 1descendant-or-self::*[contains(@id,'1')]/firstName/text()[Lokesh, Gary]

2. Java example find xml element with attribute value using xpath

Let’s look at the code which has been used to evaluate above xpath expressions to select nodes having certain attribute value.

2.1. XPath evaluate example

To evaluate xpath in java, you need to follow these steps:

  • Read XML file into org.w3c.dom.Document.
  • Create XPathFactory with its newInstance() static method.
  • Get XPath instance from XPathFactory. This object provides access to the xpath evaluation environment and expressions.
  • Create xpath expression string. Convert xpath string to XPathExpression object using xpath.compile() method.
  • Evaluate xpath against document instance created in first step. It will return list of DOM nodes from document.
  • Iterate nodes and get the test values using getNodeValue() method.

An XPath expression is not thread-safe. It is the application’s responsibility to make sure that one XPathExpression object is not used from more than one thread at any given time, and while the evaluate method is invoked, applications may not recursively call the evaluate method.

package com.howtodoinjava.demo;

import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

public class XPathExample 
{
	public static void main(String[] args) throws Exception 
	{
		//Get DOM Node for XML
		String fileName= "employees.xml";
		Document document = getDocument(fileName);
		
		String xpathExpression = "";
			
		/*******Get attribute values using xpath******/
		
		//Get all employee ids
		xpathExpression = "/employees/employee/@id";
		System.out.println( evaluateXPath(document, xpathExpression) );
		
		//Get all employee ids in HR department
		xpathExpression = "/employees/employee[department/name='HR']/@id";
		System.out.println( evaluateXPath(document, xpathExpression) );
		
		//Get employee id of 'Alex'
		xpathExpression = "/employees/employee[firstName='Alex']/@id";
		System.out.println( evaluateXPath(document, xpathExpression) );
		
		//Get employee ids greater than 5
		xpathExpression = "/employees/employee/@id[. > 5]";
		System.out.println( evaluateXPath(document, xpathExpression) );
		
		//Get employee whose id contains 1
		xpathExpression = "/employees/employee[contains(@id,'1')]/firstName/text()";
		System.out.println( evaluateXPath(document, xpathExpression) );
		
		//Get employee whose id contains 1
		xpathExpression = "descendant-or-self::*[contains(@id,'1')]/firstName/text()";
		System.out.println( evaluateXPath(document, xpathExpression) );
	}
	
	private static List<String> evaluateXPath(Document document, String xpathExpression) throws Exception 
	{
		// Create XPathFactory object
		XPathFactory xpathFactory = XPathFactory.newInstance();
		
		// Create XPath object
		XPath xpath = xpathFactory.newXPath();

		List<String> values = new ArrayList<>();
		try 
		{
			// Create XPathExpression object
			XPathExpression expr = xpath.compile(xpathExpression);
			
			// Evaluate expression result on XML document
			NodeList nodes = (NodeList) expr.evaluate(document, XPathConstants.NODESET);
			
			for (int i = 0; i < nodes.getLength(); i++) {
				values.add(nodes.item(i).getNodeValue());
			}
				
		} catch (XPathExpressionException e) {
			e.printStackTrace();
		}
		return values;
	}

	private static Document getDocument(String fileName) throws Exception 
	{
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(fileName);
		return doc;
	}
}

Program Output:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[2, 4, 8]
[3]
[6, 7, 8, 9, 10]
[Lokesh, Gary]
[Lokesh, Gary]

2.2. Model Classes

@XmlRootElement(name="employees")
@XmlAccessorType(XmlAccessType.FIELD)
public class Employees implements Serializable
{
	private static final long serialVersionUID = 1L;
	
	@XmlElement(name="employee")
	private List<Employee> employees;

	public List<Employee> getEmployees() {
		if(employees == null) {
			employees = new ArrayList<Employee>();
		}
		return employees;
	}

	public void setEmployees(List<Employee> employees) {
		this.employees = employees;
	}

	@Override
	public String toString() {
		return "Employees [employees=" + employees + "]";
	}
}
@XmlRootElement(name="employee")
@XmlAccessorType(XmlAccessType.FIELD)
public class Employee implements Serializable {

	private static final long serialVersionUID = 1L;

	@XmlAttribute
	private Integer id;
	private String firstName;
	private String lastName;
	private Department department;

	public Employee() {
		super();
	}

	public Employee(int id, String fName, String lName, Department department) {
		super();
		this.id = id;
		this.firstName = fName;
		this.lastName = lName;
		this.department = department;
	}

	//Setters and Getters

	@Override
	public String toString() {
		return "Employee [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", department="
				+ department + "]";
	}
}
@XmlRootElement(name="department")
@XmlAccessorType(XmlAccessType.FIELD)
public class Department implements Serializable {
	
	private static final long serialVersionUID = 1L;
	
	Integer id;
	String name;
	
	public Department() {
		super();
	}

	public Department(Integer id, String name) {
		super();
		this.id = id;
		this.name = name;
	}
	
	//Setters and Getters

	@Override
	public String toString() {
		return "Department [id=" + id + ", name=" + name + "]";
	}
}

Drop me your questions related to how to find xml element with attribute value using xpath.

Happy Learning !!

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.

3 thoughts on “Find xml element with attribute value using xpath in Java”

Leave a Comment

HowToDoInJava

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