2015-11-19 3 views
0

Почему следующий xpath не возвращает результаты с Saxon 9.6 в Java?Оценка XPath с Saxon не работает для nodename

//field

Странная часть I также оценивали //* и накинут результатов, сравнивающих nodeNames с «поля» и получил 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.

EDIT:

Как я догадалась документ декларирует пространство имен по умолчанию

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

и поэтому template и field элементы находятся в этом пространстве имен.

Для соответствия элементам 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