Java XPath NamespaceContext – 命名空间解析示例

Java XPath NamespaceContext – 命名空间解析示例

原文: https://howtodoinjava.com/xml/xpath-namespace-resolution-example/

在此 Java 示例中,我们将使用NamespaceContext将 XPath 命名空间解析学习为 XML 文件,该文件具有命名空间声明和各自的用法。

添加了 XML 文件的命名空间

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

<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 文档本身内任何给定命名空间前缀(作为参数传递)的命名空间声明。 因此无需单独创建命名空间映射

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 表达式。

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

上面程序的输出是:

[Data Structure, Java Core]

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

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

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/