无法使 XPath 处理复杂的命名空间



让我们从这样的XML开始:

<?xml version="1.0" encoding="UTF-8"?>
<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/" timeStamp="2009-11-26T15:21:36Z" uuid="02334fb6-3ae8-4094-9279-29ff59fc5bc8">
    <config xmlns="http://www.xfa.org/schema/xci/2.6/">
        ...
    </config>
    <template xmlns="http://www.xfa.org/schema/xfa-template/2.6/">
        <subform name="movie" w="196.85mm">
            <field name="duration" y="11.7mm" x="2.175mm" w="62mm" h="9mm">
                ...
            </field>
            <field name="imdb" y="11.7mm" x="65.675mm" w="62mm" h="9mm">
                ...
            </field>
            ...
            <subform name="directors" layout="tb" x="2.175mm" y="30.75mm" w="95.25mm">
                ...
                <field name="director" w="91.075mm" h="9mm">
                    ...
                </field>
                ...
            </subform>
            ...
        </subform>
        ...
    </template>
    ...
</xdp:xdp>

(对于那些想知道的人,它是此iText示例中使用的PDF的XFA文档的简化版本。

现在我想在NodeList中获取所有<field>元素,XPath非常适合此目的:

XPath xpath = XPathFactory.newInstance().newXPath();
xpath.setNamespaceContext(new NamespaceContext() {
    public String getNamespaceURI(String p) {
        return "http://www.xfa.org/schema/xfa-template/2.6/";
    }
    public String getPrefix(String arg0) {return null;}
    public Iterator<?> getPrefixes(String arg0) {return null;}    
});
NodeList fields = (NodeList)xpath.evaluate("//field", document, XPathConstants.NODESET);

现在这不起作用,结果是空的。我也尝试过在getNamespaceURI中返回null;如果前缀"xdp",也返回"http://ns.adobe.com/xdp/",否则null

我还尝试手动获取 <template> 元素并从该节点使用评估,使用上述NamespaceContext或返回null getNamespaceURI......

这个过于复杂的系统似乎没有什么可以工作的,我不想在不知道我做错了什么的情况下继续尝试。

您应该在路径中使用前缀,例如 //df:field然后当然确保前缀绑定到命名空间 URI,例如

xpath.setNamespaceContext(new NamespaceContext() {
    public String getNamespaceURI(String p) {
      if (p.equals("df")) {
        return "http://www.xfa.org/schema/xfa-template/2.6/";
      }
    }
    public String getPrefix(String arg0) {return null;}
    public Iterator<?> getPrefixes(String arg0) {return null;}    
});

最新更新