# Java XPath `NamespaceContext` – 名称空间解析示例

> 原文： [https://howtodoinjava.com/xml/xpath-namespace-resolution-example/](https://howtodoinjava.com/xml/xpath-namespace-resolution-example/)

在此 Java 示例中，我们将使用[`NamespaceContext`](https://docs.oracle.com/javase/7/docs/api/javax/xml/namespace/NamespaceContext.html)将 XPath 名称空间解析学习为 XML 文件，该文件具有名称空间声明和各自的用法。

## 命名空间添加了 XML 文件

我已经创建了`sample.xml`文件并将其放在类路径中。

```java
<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>

```

## 实现`NamespaceContext`以创建名称空间解析器

该名称空间解析器可以与使用了名称空间定义的任何 XML 文件一起使用。 它搜索 XML 文档本身内任何给定名称空间前缀（作为参数传递）的名称空间声明。 因此**无需单独创建名称空间映射**。

```java
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;
    }
}

```

## 使用`NamespaceResolver`并应用 XPath

现在，我们准备在 XML 文件上应用 xpath 表达式。

```java
//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);

```

上面程序的输出是：

```java
[Data Structure, Java Core]
```

## XPath 命名空间解析的完整源代码

这是上面示例的完整源代码。

```java
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;
    }
}

```

在评论部分让我知道您的问题。

学习愉快！

参考： [http://www.ibm.com/developerworks/library/x-nmspccontext/](https://www.ibm.com/developerworks/library/x-nmspccontext/)