Java XPath NamespaceContext – NameSpace Resolution Example

In this java example, we will learn XPath namespace resolution into an XML file using NamespaceContext which has namespace declarations and respective usages.

1. XML with Namespace

We have created sample.xml file and put it on the classpath for demo purpose.

<ns2:bookStore xmlns:ns2="http://bookstore.com/schemes">
	<ns2:book id="1">
		<ns2:name>Data Structure</ns2:name>
	</ns2:book>
	<ns2:book id="2">
		<ns2:name>Java Core</ns2:name>
	</ns2:book>
</ns2:bookStore>

2. Implement NamespaceContext to Create NameSpace Resolver

This namespace resolver can be used with any XML file where namespace definitions have been used. It searches for namespace declarations for any given namespace prefix – passed as a parameter – inside the XML document itself. So no need to create namespace mapping separately.

public class NamespaceResolver implements NamespaceContext 
{
  //Store the source document to search the namespaces
    private Document sourceDocument;
 
    public NamespaceResolver(Document document) {
        sourceDocument = document;
    }
 
    //The lookup for the namespace uris is delegated to the stored document.
    public String getNamespaceURI(String prefix) {
        if (prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)) {
            return sourceDocument.lookupNamespaceURI(null);
        } else {
            return sourceDocument.lookupNamespaceURI(prefix);
        }
    }
 
    public String getPrefix(String namespaceURI) {
        return sourceDocument.lookupPrefix(namespaceURI);
    }
 
    @SuppressWarnings("rawtypes")
  public Iterator getPrefixes(String namespaceURI) {
        return null;
    }
}

3. Using NamespaceResolver and Applying XPath

Now we are ready to apply the xpath expression over the XML file.

//Want to read all book names from XML
ArrayList<String> bookNames = new ArrayList<String>();
 
//Parse XML file
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true); 
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new FileInputStream(new File("sample.xml")));
 
//Get XPath expression
XPathFactory xpathfactory = XPathFactory.newInstance();
XPath xpath = xpathfactory.newXPath();
xpath.setNamespaceContext(new NamespaceResolver(doc));
XPathExpression expr = xpath.compile("//ns2:bookStore/ns2:book/ns2:name/text()"); 
 
//Search XPath expression
Object result = expr.evaluate(doc, XPathConstants.NODESET);
 
//Iterate over results and fetch book names
NodeList nodes = (NodeList) result;
for (int i = 0; i < nodes.getLength(); i++) {
  bookNames.add(nodes.item(i).getNodeValue());
}
 
//Verify book names
System.out.println(bookNames);

Program output:

[Data Structure, Java Core]

4. Complete Source Code for XPath Namespace Resolution

This is the complete source code of the above example.

import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Iterator;
 
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
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;
import org.w3c.dom.NodeList;
 
 
public class Main 
{
  public static void main(String[] args) throws Exception 
  {
    //Want to read all book names from XML
    ArrayList<String> bookNames = new ArrayList<String>();
     
    //Parse XML file
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true); 
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(new FileInputStream(new File("sample.xml")));
         
        //Get XPath expression
        XPathFactory xpathfactory = XPathFactory.newInstance();
        XPath xpath = xpathfactory.newXPath();
        xpath.setNamespaceContext(new NamespaceResolver(doc));
        XPathExpression expr = xpath.compile("//ns2:bookStore/ns2:book/ns2:name/text()"); 
         
        //Search XPath expression
        Object result = expr.evaluate(doc, XPathConstants.NODESET);
         
        //Iterate over results and fetch book names
        NodeList nodes = (NodeList) result;
        for (int i = 0; i < nodes.getLength(); i++) {
          bookNames.add(nodes.item(i).getNodeValue());
        }
         
        //Verify book names
        System.out.println(bookNames);
  }
}
class NamespaceResolver implements NamespaceContext 
{
  //Store the source document to search the namespaces
    private Document sourceDocument;
 
    public NamespaceResolver(Document document) {
        sourceDocument = document;
    }
 
    //The lookup for the namespace uris is delegated to the stored document.
    public String getNamespaceURI(String prefix) {
        if (prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)) {
            return sourceDocument.lookupNamespaceURI(null);
        } else {
            return sourceDocument.lookupNamespaceURI(prefix);
        }
    }
 
    public String getPrefix(String namespaceURI) {
        return sourceDocument.lookupPrefix(namespaceURI);
    }
 
    @SuppressWarnings("rawtypes")
  public Iterator getPrefixes(String namespaceURI) {
        return null;
    }
}

Let me know of your questions in the comments section.

Happy Learning !!

Sourcecode in Github

Comments

Subscribe
Notify of
guest
6 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.