Java 具有命名空间的文档的 XPath 解析器

Java XPath resolver for documents with namespaces

我需要在 Java 应用程序中使用 XPath 表达式查询 XML 文档。我创建了以下 类,它接受一个文件(XML 文档在本地硬盘上的位置)和一个 XPath

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

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.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
 
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
 
public class Try 
{
    public static void main(String[] args) throws Exception 
    {
        //Get DOM Node for XML
        String fileName= "xmd.xml";
        Document document = getDocument(fileName);
         
        String xpathExpression = "";
             
        /*******Get attribute values using xpath******/
         
        
        xpathExpression = "//isebel:story/dc:title/text()";
        System.out.println( evaluateXPath(document, xpathExpression) );
        
    }
     
    private static List<String> evaluateXPath(Document document, String xpathExpression) throws Exception 
    {
        // Create XPathFactory object
        XPathFactory xpathFactory = XPathFactory.newInstance();
         
        // Create XPath object
        XPath xpath = xpathFactory.newXPath();
        
        List<String> values = new ArrayList<>();
        try
        {
            // Create XPathExpression object
            XPathExpression expr = xpath.compile(xpathExpression);
             
            // Evaluate expression result on XML document
            NodeList nodes = (NodeList) expr.evaluate(document, XPathConstants.NODESET);
             
            for (int i = 0; i < nodes.getLength(); i++) {
                values.add(nodes.item(i).getNodeValue());
            }
                 
        } catch (XPathExpressionException e) {
            e.printStackTrace();
        }
        return values;
    }
 
    private static Document getDocument(String fileName) throws Exception 
    {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(fileName);
        return doc;
    }
    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;
        }
    }
}

假设现在我有以下 XML 文档。

<?xml version='1.0' encoding='UTF-8'?>
<isebel:story xmlns:isebel="http://www.isebel.eu/ns/isebel" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:html="http://www.w3.org/1999/xhtml" xml:id="xmd-s001-000-000-069" xml:lang="deu">
  <dc:identifier>de.wossidia.xmd-s001-000-000-069</dc:identifier>
  <isebel:purl>https://apps.wossidia.de/webapp/run/node/XMD-S001-000-000-069</isebel:purl>
  <dc:title>[69] Mit Peitsche und Knüppel</dc:title>
  <dc:title xml:lang="nds"/>
  <dc:title xml:lang="deu"/>
  <isebel:contents>
    <isebel:content xml:lang="nds">De Kutscher hett bi Vierecksch deent. Vierecksch het twee böse Jungens hatt, de hebben de Pier de Swänz afsnäden. Se hebben dat up sienen, dennʼ Kutscher sienen Schalm daan (ego: d. h. Kutscher als Täter angegeben, d. h. gesagt, er habe es getan). Dor het Vierecksch dennʼ Kutscher slagen, dat de Schoh vull Bloot stahn hebben bet up de Schänen. Dor het he sik verdrunken inʼn Radenschen See. De mööt hier jo begraben warden (nescit, wo). De ward jo haalt. As se kamen bi ʼn Kirchhoff, koenen keen Pier em trecken, un dor warden von sülben de Klocken gahn. Dor warden Ossen vorspannt, de trecken em hen na ʼn Gerichtsbarg (in Wattmannshagen), dor is he begraben. De Swester het ʼn drögen Hasselstock hatt, dennʼ steckt se em up sien Graff un seggt: Wenn de utgräunt, is ehr Broder selig storben. De is utgräunt, dor is se ruhig wäst.

Erzähler: Frau Oppermann, Hohenfelde b. Laiendorf, Kreis Neustrelitz; Aufzeichner: Wossidlo, 15. 6. 1913.</isebel:content>
    <isebel:content xml:lang="deu">Der Kutscher hat bei der alten Viereck gedient. Die alte Viereck hat zwei böse Jungen gehabt. Die haben den Pferden die Schwänze abgeschnitten. Sie haben das aber auf den Kutscher geschoben. Da hat die Vierecken den Kutscher geschlagen, daß die Schuhe voll Blut gestanden haben bis an die Schienbeine. Da hat er sich im Radenschen See ertränkt. Er muß ja hier begraben werden (Erzähler weiß nicht wo). Er wird ja auch geholt. Als sie beim Kirchhof vorbeikommen, können ihn die Pferde nicht ziehen und die Glocken beginnen von selbst zu läuten. Da werden Ochsen vorgespannt, die ziehen ihn bis zum Gerichtsberg. In Wattmannshagen ist er begraben. Die Schwester hat einen trocknen Haselstock gehabt, den steckt sie auf sein Grab und sagt: wenn der ausschlägt, ist ihr Bruder selig gestorben. Er ist ausgeschlagen, da ist sie ruhig gewesen.</isebel:content>
  </isebel:contents>
</isebel:story>

我想得到:

[[69] Mit Peitsche und Knüppel]

它不起作用有人可以帮助

您的 XML 不是 namespace-well-formed:它使用未定义的命名空间前缀。

首先修复您的 XML。然后将您的 getNamespaceURI() 方法修复为 return 每个使用的命名空间前缀的正确命名空间 URI。

请参阅 以获取工作 getNamespaceURI() 方法的示例。