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