XPath local-name example
Continuing on the series ofexamples aboutXPath, we will see how we can use thelocal-name function in Java. We use thisXPath function we need to work withnamespaces.
What are namespaces?
Namespaces are used to avoid conflicts in the tag-names. The tags have a prefix defined by thexmlns 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>
TheXPath functions we have been discussing so far for selecting nodes are useful for querying theXML when the XML has default namespace. However, if theXML has a namespace defined and theXML the query won’t return any result at all.
Consider the example below:
TheXML 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 thelocal-name() function. Thelocal-name() function ignores the namespace and returns the query results as if theXML did not have any namespace.
Try to avoid
local-name() when you have conflicting tag names.Consider implementingNamespaceContext for such a case.Let’s look at an example to see how to use thelocal-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 theXPath query ignored the namespace prefix, the XPath Expression returns the expected answer.
Conclusion:
Here we tried to understand the effect of namespaces onXPath querying and how we can circumvent the effect of the same while querying theXML document in a simple manner.
You can download the source code of this example here:XPathLocalFunctionDemo.zip

Thank you!
We will contact you soon.



