2015-11-19 25 views
0

为什么以下xpath不会在Java中使用Saxon 9.6返回任何结果?使用Saxon进行XPath评估对于节点名称不起作用

//field

奇怪的是我还评价//*和挂绕在与“场”比较节点名的结果,并得到了889个命中为我的文件。

下面

全codeexample:

初始化和运行测试:

DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); 
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); 
Document doc = dBuilder.parse(file); 


test(doc, "//*"); 
test(doc, "//field"); 

测试执行代码:

private void test(Document doc, String xpathString) throws Exception { 
    System.setProperty("javax.xml.xpath.XPathFactory:" + NamespaceConstant.OBJECT_MODEL_SAXON, "net.sf.saxon.xpath.XPathFactoryImpl"); 
    XPathFactory xpf; 
    xpf = XPathFactory.newInstance(NamespaceConstant.OBJECT_MODEL_SAXON); 

    XPath xpath = xpf.newXPath(); 

    XPathExpression expr = xpath.compile(xpathString); 

    Object result = expr.evaluate(doc, XPathConstants.NODESET); 
    NodeList nodes = (NodeList) result; 

    int fieldHits = 0; 
    for (int i = 0; i < nodes.getLength(); i++) { 
     Node node = nodes.item(i); 
     String name = node.getNodeName(); 
     fieldHits = "field".equals(nodes.item(i).getNodeName()) ? fieldHits + 1 : fieldHits; 
    } 

    System.out.println("#hits total: " + nodes.getLength()); 
    System.out.println("#hits 'field': " + fieldHits); 
} 

输出:

#hits total: 26256 
#hits 'field': 889 
#hits total: 0 
#hits 'field': 0 

示例XML文档(谢谢到WERO我现在知道它是与命名空间):

<?xml version="1.0" encoding="UTF-8"?> 
<?xfa generator="AdobeLiveCycleDesignerES_V9.0.1.0.20091206.1.615263" APIVersion="3.2.9310.0"?> 
<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/" timeStamp="2015-11-17T07:12:49Z" uuid="262c190c-1563-4ae8-ae6e-4c8d59494a3c"> 
<template xmlns:xliff="urn:oasis:names:tc:xliff:document:1.1" xmlns="http://www.xfa.org/schema/xfa-template/2.8/"> 
    <field name="A"></field> 
    <field name="B"></field> 
    <field name="C"></field> 
    <field name="D"></field> 
    <field name="E"></field> 
    <field name="F"></field> 
</template> 
</xdp:xdp> 

回答

1

最有可能的解释是,你field元素有一个非空的命名空间URI,因此不会被你的XPath表达式匹配。

编辑:

正如我猜你的文档声明默认的命名空间

xmlns="http://www.xfa.org/schema/xfa-template/2.8/" 

等等templatefield元素在该命名空间。

要匹配field元素,您或者需要tweak您的XPath查询以声明该名称空间或仅搜索本地名称。

+0

谢谢,它确实与名称空间有关。现在我可以创建一个简单的例子。你可以看看吗? :) – sotix

+0

明白了,非常感谢:) – sotix

1

请注意,如果您要使用s9api接口而不是JAXP,则可以利用XPath 2.0中的功能为XPath表达式中的元素名称设置默认名称空间。您的代码将如下所示:

private void test(Document doc, String xpathString) throws Exception { 
    Processor proc = new Processor(false); 
    XdmNode docNode = proc.newDocumentBuilder().wrap(doc); 
    XPathCompiler xpath = proc.newXPathCompiler(); 
    xpath.declareNamespace("", "http://www.xfa.org/schema/xfa-template/2.8/"); 
    XdmValue result = xpath.evaluate(xpathString, docNode); 
    int fieldHits = 0; 
    for (XdmItem item : result) { 
     String name = ((XdmNode)node).getNodeName().getLocalName(); 
     fieldHits = "field".equals(name) ? fieldHits + 1 : fieldHits; 
    } 

    System.out.println("#hits total: " + nodes.getLength()); 
    System.out.println("#hits 'field': " + fieldHits); 
} 
+0

我不知道s9api,会看看它。谢谢 :) – sotix