XPath is a language for finding information in an XML file. You can say that XPath is (sort of) SQL for XML files. XPath is used to navigate through elements and attributes in an XML document. You can also use XPath to traverse through an XML file in Java. XPath comes with powerful expressions that can be used to parse an xml document and retrieve relevant information. For demo, let us consider an xml file that holds information of employees.
<?xml version="1.0"?>
<Employees>
<Employee emplid="1111" type="admin">
<firstname>John</firstname>
<lastname>Watson</lastname>
<age>30</age>
<email>[email protected]</email>
</Employee>
<Employee emplid="2222" type="admin">
<firstname>Sherlock</firstname>
<lastname>Homes</lastname>
<age>32</age>
<email>[email protected]</email>
</Employee>
<Employee emplid="3333" type="user">
<firstname>Jim</firstname>
<lastname>Moriarty</lastname>
<age>52</age>
<email>[email protected]</email>
</Employee>
<Employee emplid="4444" type="user">
<firstname>Mycroft</firstname>
<lastname>Holmes</lastname>
<age>41</age>
<email>[email protected]</email>
</Employee>
</Employees>
Code language: HTML, XML (xml)
I have saved this file at path C:\employees.xml
. We will use this xml file in our demo and will try to fetch useful information using XPath. Before we start lets check few facts from above xml file.
- There are 4 employees in our xml file
- Each employee has a unique employee id defined by attribute
emplid
- Each employee also has an attribute
type
which defines whether an employee is admin or user. - Each employee has four child nodes:
firstname
,lastname
,age
andemail
- Age is a number
Let’s get started…
1. Learning Java DOM Parsing API
In order to understand XPath, first we need to understand basics of DOM parsing in Java. Java provides powerful implementation of domparser in form of below API.
1.1 Creating a Java DOM XML Parser
First, we need to create a document builder using DocumentBuilderFactory
class. Just follow the code. It’s pretty much self explainatory.
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
//...
DocumentBuilderFactory builderFactory =
DocumentBuilderFactory.newInstance();
DocumentBuilder builder = null;
try {
builder = builderFactory.newDocumentBuilder();
} catch (ParserConfigurationException e) {
e.printStackTrace();
}
Code language: Java (java)
1.2 Parsing XML with a Java DOM Parser
Once we have a document builder object. We uses it to parse XML file and create a document object.
import org.w3c.dom.Document;
import java.io.IOException;
import org.xml.sax.SAXException;
//...
try {
Document document = builder.parse(
new FileInputStream("c:\\employees.xml"));
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Code language: Java (java)
In above code, we are parsing an XML file from filesystem. Sometimes you might want to parse XML specified as String value instead of reading it from file. Below code comes handy to parse XML specified as String.
String xml = ...;
Document xmlDocument = builder.parse(new ByteArrayInputStream(xml.getBytes()));
Code language: Java (java)
1.3 Creating an XPath object
Once we have document object. We are ready to use XPath. Just create an xpath object using XPathFactory.
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory;
//...
XPath xPath = XPathFactory.newInstance().newXPath();
Code language: Java (java)
1.4 Using XPath to parse the XML
Use xpath object to complie an XPath expression and evaluate it on document. In below code we read email address of employee having employee id = 3333. Also we have specified APIs to read an XML node and a nodelist.
String expression = "/Employees/Employee[@emplid='3333']/email";
//read a string value
String email = xPath.compile(expression).evaluate(xmlDocument);
//read an xml node using xpath
Node node = (Node) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODE);
//read a nodelist using xpath
NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);
Code language: Java (java)
2. Learning XPath Expressions
As mentioned above, XPath uses a path expression to select nodes or list of node from an xml document. Heres a list of useful paths and expression that can be used to select any node/nodelist from an xml document.
Expression | Description |
---|---|
nodename | Selects all nodes with the name “nodename” |
/ | Selects from the root node |
// | Selects nodes in the document from the current node that match the selection no matter where they are |
. | Selects the current node |
.. | Selects the parent of the current node |
@ | Selects attributes |
employee | Selects all nodes with the name “employee” |
employees/employee | Selects all employee elements that are children of employees |
//employee | Selects all book elements no matter where they are in the document |
Below list of expressions are called Predicates. The Predicates are defined in square brackets [ … ]. They are used to find a specific node or a node that contains a specific value.
Path Expression | Result |
---|---|
/employees/employee[1] | Selects the first employee element that is the child of the employees element. |
/employees/employee[last()] | Selects the last employee element that is the child of the employees element |
/employees/employee[last()-1] | Selects the last but one employee element that is the child of the employees element |
//employee[@type='admin'] | Selects all the employee elements that have an attribute named type with a value of ‘admin’ |
There are other useful expressions that you can use to query the data. Read this w3school page for more details: http://www.w3schools.com/xpath/xpath_syntax.asp
3. Examples: Query XML document using XPath
Below are few examples of using different expressions of xpath to fetch some information from xml document.
3.1 Read firstname of all employees
Below expression will read firstname
of all the employees.
String expression = "/Employees/Employee/firstname";
System.out.println(expression);
NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
System.out.println(nodeList.item(i).getFirstChild().getNodeValue());
}
Code language: Java (java)
Output:
John Sherlock Jim Mycroft
3.2 Read a specific employee using employee id
Below expression will read employee information for employee with emplid = 2222. Check how we used API to retrieve node information and then traveresed this node to print xml tag and its value.
String expression = "/Employees/Employee[@emplid='2222']";
System.out.println(expression);
Node node = (Node) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODE);
if(null != node) {
nodeList = node.getChildNodes();
for (int i = 0;null!=nodeList && i < nodeList.getLength(); i++) {
Node nod = nodeList.item(i);
if(nod.getNodeType() == Node.ELEMENT_NODE)
System.out.println(nodeList.item(i).getNodeName() + " : " + nod.getFirstChild().getNodeValue());
}
}
Code language: Java (java)
Output:
firstname : Sherlock
lastname : Homes
age : 32
email : sherlock@sh.com
Code language: CSS (css)
3.3 Read firstname of all employees who are admin
This is again a predicate example to read firstname
of all employee who are admin (defined by type=admin).
String expression = "/Employees/Employee[@type='admin']/firstname";
System.out.println(expression);
NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
System.out.println(nodeList.item(i).getFirstChild().getNodeValue());
}
Code language: Java (java)
Output:
John Sherlock
3.4 Read firstname of all employees who are older than 40 year
See how we used predicate to filter employees who has age > 40
.
String expression = "/Employees/Employee[age>40]/firstname";
NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
System.out.println(nodeList.item(i).getFirstChild().getNodeValue());
}
Code language: Java (java)
Output:
Jim Mycroft
3.5 Read firstname of first two employees (defined in xml file)
Within predicates, you can use position()
to identify the position of xml element. Here we are filtering first two employees using position().
String expression = "/Employees/Employee[position() <= 2]/firstname";
NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
System.out.println(nodeList.item(i).getFirstChild().getNodeValue());
}
Code language: Java (java)
Output:
John Sherlock
4. Complete Java source code
In order to execute this source, just create a basic Java project in your IDE or just save below code in Main.java and execute. It will need employees.xml
file as input. Copy the employee xml defined in start of this tutorial at c:\\employees.xml
.
package net.viralpatel.java;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class Main {
public static void main(String[] args) {
try {
FileInputStream file = new FileInputStream(new File("c:/employees.xml"));
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document xmlDocument = builder.parse(file);
XPath xPath = XPathFactory.newInstance().newXPath();
System.out.println("*************************");
String expression = "/Employees/Employee[@emplid='3333']/email";
System.out.println(expression);
String email = xPath.compile(expression).evaluate(xmlDocument);
System.out.println(email);
System.out.println("*************************");
expression = "/Employees/Employee/firstname";
System.out.println(expression);
NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
System.out.println(nodeList.item(i).getFirstChild().getNodeValue());
}
System.out.println("*************************");
expression = "/Employees/Employee[@type='admin']/firstname";
System.out.println(expression);
nodeList = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
System.out.println(nodeList.item(i).getFirstChild().getNodeValue());
}
System.out.println("*************************");
expression = "/Employees/Employee[@emplid='2222']";
System.out.println(expression);
Node node = (Node) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODE);
if(null != node) {
nodeList = node.getChildNodes();
for (int i = 0;null!=nodeList && i < nodeList.getLength(); i++) {
Node nod = nodeList.item(i);
if(nod.getNodeType() == Node.ELEMENT_NODE)
System.out.println(nodeList.item(i).getNodeName() + " : " + nod.getFirstChild().getNodeValue());
}
}
System.out.println("*************************");
expression = "/Employees/Employee[age>40]/firstname";
nodeList = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);
System.out.println(expression);
for (int i = 0; i < nodeList.getLength(); i++) {
System.out.println(nodeList.item(i).getFirstChild().getNodeValue());
}
System.out.println("*************************");
expression = "/Employees/Employee[1]/firstname";
System.out.println(expression);
nodeList = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
System.out.println(nodeList.item(i).getFirstChild().getNodeValue());
}
System.out.println("*************************");
expression = "/Employees/Employee[position() <= 2]/firstname";
System.out.println(expression);
nodeList = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
System.out.println(nodeList.item(i).getFirstChild().getNodeValue());
}
System.out.println("*************************");
expression = "/Employees/Employee[last()]/firstname";
System.out.println(expression);
nodeList = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
System.out.println(nodeList.item(i).getFirstChild().getNodeValue());
}
System.out.println("*************************");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (XPathExpressionException e) {
e.printStackTrace();
}
}
}
Code language: Java (java)
That’s all folks :)
Nice tutorial, infact i was searching for this thanks..
This is a great tutorial. Thanks much for all your help!
You took the time to nicely demonstrate the basics of XPath XML parsing.
Keep up the good work!
Thanks! Very useful for exam preparation :)
Thanks for your useful tutorial.
I have a question that I’d be glad if you answer me.
If I want to read, tag elements, what should I do?
I tried it: System.out.println(nod.getAttributes());
but the output is : com.sun.org.apache.xerces.internal.dom.AttributeMap@1729854
so I tried it: System.out.println((Element)nod.getAttributes());
but the output is: Exception in thread “main” java.lang.ClassCastException: com.sun.org.apache.xerces.internal.dom.AttributeMap cannot be cast to org.w3c.dom.Element
now Im’Confused. please guide me how should I read them?
Thanks
Superb tips..Viral..keep up
ur tutorials helped me alot for understanding xml to db data transfer………tooo goood …. keep going on…and thank a lalot
Thank you, ViralPatel, it’s nice!
It helps me a lot.
Thanks Viral
Thanks ! It was quite useful
Excellent Tutorial Viral, Thanks
Hi i need to create following xml file using DOM in java can you help me for the same … it’s very urgent.
Yo may want to show imports when you provide a sample. What class of NODE is that? SOAP? Why would I need SOAP import to use XPath? All these questions come when you do not provide complete sample with tutorial. We simply are not experimenting with guesses and class cast exceptions.
Check the complete Java source at the end of tutorial. The Node class is
org.w3c.dom.Node
.How do I parse String? Honestly it is overkill requiring File to parse a string. Most of XML documents as simply strings and as such they should not need file or URI anywhere. Location is not function of parsing and it is very poor design of the interface. The only reasonable interface is either String or InputStream.
I am switching to JIBX or JAXB.
If you do not agree than explain to me what is purpose of DocumentBuilderFactory and then DocumentBuilder. Those are creation OO patterns and there is no reason to use those (poor design patterns) if you look at pattern motivation by book. I would recommend those who created them to take a look at “Gang of Four” book and start using head. We have something as simple as constructor and we do not need singletons or builders to parse document.
Waste of precious work on unnecessary operations to parse using XPath witch handling five types of exceptions when we need only two realistaically.
Thanks. I need this badly.
It is very useful
Thank once again. It helped me a lot :). Thanks for this wonderful documentation with clear explanation.
Great stuff, straight to the point
Hi.This promlem:
my xml:
how to take ‘33,32,35,37,37’ from second , ?
thanks.
Very nice tutorial. Explained very nicely even for newbies :). Thanks a lot
How to parse the blow xml using xpath
I am getting NullPointerException when reading pubmed_abbreviation tag.
Please help with some ideas.
abcdefghijklmno
i want to write an xpath to get
abcdefghijlkmno as output.
how to do it??
i want abcdefghijklmno as output what xpath should i write
what it is work on jdk version?
is it work for jdk1.5?
Extremly x 100 !!!! nice tutorial. :)
This is wonderful documentation with clear explanation.
our requirement is based on the target system schema we need to map the source and traget system to match to traget system and again write back to XML.
Input is XML and
Expected output : XML
Good stuff! I needed to make the switch from PHP XPath to Java XPath, this tutorial really helped!
Nice Tutorial ……
very nice tutorial
its simply clear
Hi i m making a search box in jsp,Its like i am reading the value entered in search box and comaring it with xml and displaying the desired result.
Please reply quickly as its urgent on how it can be done?
Thank you very much Viral ;-)
I am using below method to get Document object
Now problem is the response have some special characters(&) because of which parsing fails . how to solve this problem
Hi,
xpath expressions doesn’t work in jdk 1.7.
this expression will work on jdk 1.6.
String expression = “/Response/Item[@id=’1′]/Value”;
can you give a sample to filter attribute using @id?
example xml:
Test 1
Test 2
Any tips?
Br,
Rico
thanks,good job
this tutorial is awesome, thanks!
Man, you’re awesome. This is by far the best XML parsing tutorial I’ve read on the internet. Thanks for the amazing write-up. Using XPath suits my need as I need to process each tag individually.
Thank you. Very useful Blog. Simple and Beautifully Explained.
This is just great. Few days back, I was searching exactly the same thing and here you are. Keep it up.
Hi Anuj, Glad it is useful :)
first of all thanks .
really its usefull examlple..
i have one more Doubt
how u do get type and empid in same time ????/
thanks advance
Why don’t you explain namespaces with XPath?
Very nice tutorial :) Will be much appreciated if you have provided xpath example for a xml that contains namespace. Keep up the good work :)
thanks so much:)
great tutorial
Thanks a lot!!!
Great work dude…it was really usefull for me!
Thnx for tutorial .. but i m not able to find out solution of my problem anywhere ..
if anyone hv answer please reply..
consider below XML
Now i want to get value for attribute dept .i.e. ‘hi-tech’ ..
/Employees/@dept
One of the most comprehensive and straightforward tutorial for using XPath that i have found on the internet. Great work Viral.
Very good examples. Thank you for sharing it.
Thanks for tutorial. Can we compare two node difference from two files.
consider below two xml files
file1.xml
============================
file1.xml
=======================
I wants to check every node from file2 is present in file1, if present then chk its matching with file1 node. if not matchingthen get difference.
if anyone hv answer please reply..
Thanks.
how can i read and print unicoded string….where should i hav to add utf-8 in the given code…
Very interesting, thks.
Viral: A wonderful article. Thanks a bunch. Pl. keep this good work going.
Nice Article
Really useful information
nice yr..
nice
nice,,
I’m quite lazy nowadays. I just use castor to parse XML.
Hi Patel,
I have below XML snippet ,I am struggling since last one day how to parse this even though many techniques.Can you plz help me out,how can I parse this.
Really a nice article,, helps alot who want to learn programming language.
Nice Article to parse XML file using XPath.
Nice Article….
Nice
nice article
nice….
expression = “/Employees/Employee/firstname”;
=> change to FULL Lowercase, else not working.am using Java 8
Thank yo Divine. It was running earlier on my machine. Your suggestion worked.
nice..
its nice..
nice tutorial .. thanks :)
cheersss…
Nice article, easy to follow.
Hi guys ,
I dont know why the program doesnt work some hepl please
Very good article
Hi can you parse the XBRL files through this method as well?
Hi can you parse the XBRL files through this method as well?
Hi Viral,
Document document = builder.parse(new FileInputStream(“c:\\employees.xml”));
its for the file located in c:\ but if I want to use file in values folder then
How can I get that file using parse.
I’m new to android. Please explain
Thanks
Veena/.
Hello,
based on your example I would like to get the list of the employees, from some documentation I found that the syntax of the query should be
//Employees/Employee
or
//Employees/Employee[@*]
but it does not work.
Any suggestion?
Thanks
Mirco
Really, really helpful and well done structured!
Thank you so much, dude! :-)
//employee Selects “all book elements” no matter where they are in the document
Shouldn’t this be “all employee elements”?
dear site providers, please make your XML parser work properly or disable it for good
ok now I replace the start bracket of every tag, perhaps the comment parser will then get it:
{?xml version=”1.0″ encoding=”UTF-8″?>
{map xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:noNamespaceSchemaLocation=”C:\Users\haeg\Documents\Neo4j\MiniMapFillRessources\map.xsd”>
{rooms>
{room>
{x>0{/x>
{y>0{/y>
{area>Brinstar{/area>
{zone>normal{/zone>
{content>standardContent{/content>
{/room>
{room>
{x>-1{/x>
{y>0{/y>
{area>Crateria{/area>
{zone>secret{/zone>
{content>item{/content>
{/room>
{/rooms>
{gates>
{gate>
{fromRoom>
{x>0{/x>
{y>0{/y>
{/fromRoom>
{toRoom>
{x>-1{/x>
{y>0{/y>
{/toRoom>
{type>NormalHatch{/type>
{/gate>
{/gates>
{/map>
sry if it’s a bit unreadable, there was no other way
also, the XML is aligned, which the parser also threw away
which means it’s like
_TAG_
_WHITESPACES_ _SUBTAG_ content _SUBTAG_END_
_TAG_END_
any idea what’s going wrong with my code?
solved
found out that XPath in Java doesn’t get along with aligned XML
you can erase all my comments
Can any one tell me what is the xPath expression for getting room name for above xml file?
Thank you very much for this tutorial. its actually giving me an insight of an xpath which is new to me. As much as i am new to Xpath, i am writing my Msc. Thesis using this technology on the topic ” securing web level applications using xpath injections” i am therefore appealing to this honourable members on this platform to assist me with all the technical ideas and expertise to may my research a success. THANK YOU.
Thanks for sharing nice post
Really good tutorial! Thank you very much.
NB: link to w3school has changed.. the correct is: https://www.w3schools.com/xml/xpath_syntax.asp
great article, how to read a list with 1 or more records? so it reads only the first occurrence and then the error “java.lang.NullPointerException” occurs?
cq0001Cachorro quente – G18.00sl001SalmÃo com legumes – 300 grs144.90
NodeList nodeList = (NodeList) xPath.compile(expression19).evaluate(xmlDocument, XPathConstants.NODESET);
String itemsStr = “”;
logger.info(“QTD DE ITENS=” + nodeList.getLength());
String id = “”;
String description = “”;
String quantity = “”;
String amount = “”;
Element docEle = xmlDocument.getDocumentElement();
NodeList nl = docEle.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
logger.info("I=" + i);
if (nl.item(i).getNodeType() == Node.ELEMENT_NODE) {
Element el = (Element) nodeList.item(i);
logger.info("EL = " + el.toString());
id = el.getElementsByTagName("id").item(i).getTextContent();
logger.info("id = " + id);
description = el.getElementsByTagName("description").item(i).getTextContent();
logger.info("description = " + description);
quantity = el.getElementsByTagName("quantity").item(i).getTextContent();
logger.info("quantity = " + quantity);
amount = el.getElementsByTagName("amount").item(i).getTextContent();
logger.info("amount = " + amount);
itemsStr = itemsStr + "{\"id\":\"" + id + "\"," + "\"description\":\"" + description + "\"," + "\"price\":\"" + amount + "\"," + "\"quantity\":\"" + quantity + "\"}" + ",";
}
}
Oh! You have really taken pains to give us something really worthy. Thanks for the tutorial
How can i get firstname as well as last name where age >30?