# 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
Data Structure
Java Core
```
## 实现`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 bookNames = new ArrayList();
//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 bookNames = new ArrayList();
//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/)