XPath

XPath local-name example

Continuing on the series of examples about XPath, we will see how we can use the local-name function in Java. We use this XPath function we need to work with namespaces.

What are namespaces?

Namespaces are used to avoid conflicts in the tag-names. The tags have a prefix defined by the xmlns attribute(short for XML namespace).

 
 

Let’s see an example of an XML file with namespace:


<cr:cricketers xmlns:cr="http://www.example.com/">
	<cr:cricketer type="righty">
		<name>MS Dhoni</name>
		<role>Captain</role>
		<position>Wicket-Keeper</position>
	</cr:cricketer>
</cr:cricketers>

The XPath functions we have been discussing so far for selecting nodes are useful for querying the XML when the XML has default namespace. However, if the XML has a namespace defined and the XML the query won’t return any result at all.

Consider the example below:

The XML file has a namespace, and the tags are appended with a prefix.

cricketTeam_info.xml:


<?xml version="1.0" encoding="UTF-8"?>

<cr:cricketers xmlns:cr="http://www.example.com/">
	<cr:cricketer type="righty">
		<name>MS Dhoni</name>
		<role>Captain</role>
		<position>Wicket-Keeper</position>
	</cr:cricketer>
	<cr:cricketer type="lefty">
		<name>Shikhar Dhawan</name>
		<role>              Batsman</role>
		<position>Point</position>
	</cr:cricketer>
	<cr:cricketer type="righty">
		<name>Virat Kohli</name>
		<role>Batsman</role>
		<position>cover</position>
	</cr:cricketer>
	<cr:cricketer type="righty">
		<name>Shami</name>
		<role>Bowler</role>
		<position>SquareLeg</position>
	</cr:cricketer>
	<cr:cricketer type="lefty">
		<name>Zaheer Khan</name>
		<role>Bowler</role>
		<position>FineLeg</position>
	</cr:cricketer>
</cr:cricketers>

Let’s consider the below code snippet. It should display the name of the first cricketer node.


XPathExpression expr = xpath.compile("//cricketer/name/text()");
String name = (String) expr.evaluate(doc, XPathConstants.STRING);
System.out.println("The cricketer name is : " + name);


Output:


The cricketer name is : 

As you can see, since there is no namespace configured in the XPath expression, we don’t find any matching nodes. The XPath Expression is looking for default namespace but the document is with a different namespace.

local-name() function to the rescue!

To resolve this problem of namespaces we have to use the local-name() function. The local-name() function ignores the namespace and returns the query results as if the XML did not have any namespace.

TIP:
Try to avoid local-name() when you have conflicting tag names.Consider implementing NamespaceContext for such a case.

Let’s look at an example to see how to use the local-name() function:


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

import org.w3c.dom.Document;


public class XpathLocalFunctionDemo
{
	public static void main(String[] args) throws Exception
	{

		DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
		documentBuilderFactory.setNamespaceAware(true);
		DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
		Document doc = documentBuilder.parse("src/cricketTeam_info.xml");

		XPathFactory xpathFactory = XPathFactory.newInstance();
		XPath xpath = xpathFactory.newXPath();

		XPathExpression expr = xpath.compile("//*[local-name()='cricketer']/name/text()");
		String type = (String) expr.evaluate(doc, XPathConstants.STRING);
		System.out.println("The cricketer name is : " + type);


	}
}

Output:


The cricketer name is : MS Dhoni

Once the XPath query ignored the namespace prefix, the XPath Expression returns the expected answer.

Conclusion:

Here we tried to understand the effect of namespaces on XPath querying and how we can circumvent the effect of the same while querying the XML document in a simple manner.

Download
You can download the source code of this example here: XPathLocalFunctionDemo.zip

Chandan Singh

Chandan holds a degree in Computer Engineering and is a passionate software programmer. He has good experience in Java/J2EE Web-Application development for Banking and E-Commerce Domains.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button