为什么 XPath namespace-uri() 不能在 Java 中开箱即用?



我试图使用XPath中的namespace-uri()函数根据节点的完全限定名称检索节点。这个在线XPath测试器中的查询//*[local-name() = 'customerName' and namespace-uri() = 'http://example.com/officeN']正确地返回了相关节点。然而,下面的自包含Java类不检索任何东西。我用namespace-uri()做错了什么?

import java.io.StringReader;
import javax.xml.parsers.DocumentBuilderFactory;
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;
import org.xml.sax.InputSource;
public class Test{
    public static void main(String[] args)throws Exception {
        XPathExpression expr = XPathFactory.newInstance().newXPath().compile(
                "//*[local-name() = 'customerName' and namespace-uri() = 'http://example.com/officeN']");
        String xml=
            "<Agents xmlns:n="http://example.com/officeN">n"+
            "t<n:Agent>ntt<n:customerName>Joe Shmo</n:customerName>nt</n:Agent>n"+
            "t<n:Agent>ntt<n:customerName>Mary Brown</n:customerName>nt</n:Agent>n</Agents>";
        System.out.println(xml);
        Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
        NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
        System.err.println("nnNodes:");
        for (int i = 0; i < nodes.getLength(); i++) {
            System.err.println(nodes.item(i));
        }
    }
}

查询看起来不错。你还需要声明你的DocumentBuilderFactory为"命名空间感知"。

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));

最新更新