Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-XPath-如何以相同的方式管理不同的表达式_Java_Xml_Xpath_Saxon - Fatal编程技术网

Java-XPath-如何以相同的方式管理不同的表达式

Java-XPath-如何以相同的方式管理不同的表达式,java,xml,xpath,saxon,Java,Xml,Xpath,Saxon,我有以下代码示例: package com.test.xml; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathExpressionException; i

我有以下代码示例:

package com.test.xml;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl;
import net.sf.saxon.xpath.XPathFactoryImpl;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilderFactory;

import static javax.xml.xpath.XPathConstants.NODESET;
import static org.w3c.dom.Node.ATTRIBUTE_NODE;

public class MyMainClass {

    public static void main(String[] args) throws XPathExpressionException, IOException, SAXException, ParserConfigurationException {
        Arrays.stream(args).forEach(System.out::println);

        DocumentBuilderFactory factory = new DocumentBuilderFactoryImpl();
        DocumentBuilder documentBuilder = factory.newDocumentBuilder();
        Document document = documentBuilder.parse(new File(MyMainClass.class.getClassLoader().getResource("demo.xml").getFile()));
        Node root = document.getFirstChild();

        String expression = "//TestAttribute/@value";
        XPathFactory xpathFactory = new XPathFactoryImpl();
        XPath xpath = xpathFactory.newXPath();
        XPathExpression xpathExpression = xpath.compile(expression);
        Object evaluation = xpathExpression.evaluate(root, NODESET);
        List<String> list = toStringList((NodeList)evaluation);

        list.forEach(System.out::println);
    }

    private static List<String> toStringList(NodeList nodeList) {
        final int size = nodeList.getLength();
        List<String> strings = new ArrayList<>(size);
        for (int i = 0; i < size; i++) {
            Node item = nodeList.item(i);
            if (item.getNodeType() == ATTRIBUTE_NODE) {
                strings.add(item.getTextContent());
            }
        }
        return strings;
    }
}
这是工作正常,我没有任何问题。现在我想支持另一种表达式,如:名称空间uri(/*)

如果我替换此表达式:

        String expression = "namespace-uri(/*)";
        XPathFactory xpathFactory = new XPathFactoryImpl();
        XPath xpath = xpathFactory.newXPath();
        XPathExpression xpathExpression = xpath.compile(expression);
        Object evaluation = xpathExpression.evaluate(root, NODESET);
        List<String> list = toStringList((NodeList)evaluation);
我的问题是:

  • 如何管理这些不同的表达式
  • 如何计算表达式,然后检查类型

谢谢大家!

您在saxon帮助论坛上问了同样的问题。为了记录在案,这里是我的答案。请避免日后交叉投寄

这是JAXP XPath API的弱点之一,当您使用更丰富的类型系统迁移到XPath 2.0时,这一弱点变得尤为突出:当您执行XPath表达式时,您必须说明预期的结果是什么

我建议转到s9api。在s9api中,您不必说明期望的结果类型。此表达式的XPathSelector.evaluate()将返回XdmAtomicValue。可以使用getTypeName()方法确定其XDM类型

请注意,除非您有非常充分的理由使用DOM作为树模型,否则我不推荐使用它。它是一个设计糟糕的API,与XDM没有很好的一致性(特别是在名称空间领域),并且不是线程安全的。优先使用Saxon的默认TinyTree:它可以快10倍

something
other
        String expression = "namespace-uri(/*)";
        XPathFactory xpathFactory = new XPathFactoryImpl();
        XPath xpath = xpathFactory.newXPath();
        XPathExpression xpathExpression = xpath.compile(expression);
        Object evaluation = xpathExpression.evaluate(root, NODESET);
        List<String> list = toStringList((NodeList)evaluation);
Exception in thread "main" net.sf.saxon.trans.XPathException: Cannot convert XPath value to Java object: required class is org.w3c.dom.NodeList; supplied value has type xs:anyURI
    at net.sf.saxon.dom.DOMObjectModel.convertXPathValueToObject(DOMObjectModel.java:422)
    at net.sf.saxon.dom.DOMObjectModel$7.convert(DOMObjectModel.java:205)
    at net.sf.saxon.xpath.XPathExpressionImpl.evaluate(XPathExpressionImpl.java:242)
    at com.test.xml.MyMainClass.main(MyMainClass.java:41)
--------------- linked to ------------------
javax.xml.xpath.XPathExpressionException: net.sf.saxon.trans.XPathException: Cannot convert XPath value to Java object: required class is org.w3c.dom.NodeList; supplied value has type xs:anyURI
    at net.sf.saxon.xpath.XPathExpressionImpl.evaluate(XPathExpressionImpl.java:247)
    at com.test.xml.MyMainClass.main(MyMainClass.java:41)
Caused by: net.sf.saxon.trans.XPathException: Cannot convert XPath value to Java object: required class is org.w3c.dom.NodeList; supplied value has type xs:anyURI
    at net.sf.saxon.dom.DOMObjectModel.convertXPathValueToObject(DOMObjectModel.java:422)
    at net.sf.saxon.dom.DOMObjectModel$7.convert(DOMObjectModel.java:205)
    at net.sf.saxon.xpath.XPathExpressionImpl.evaluate(XPathExpressionImpl.java:242)
    ... 1 more