XPath获取元素标记序列(Java/Saxon)
我将Java与Saxon HE 9.4一起使用,因此我可以获得XPath 2.0支持 给定以下XML实例文档:XPath获取元素标记序列(Java/Saxon),java,xpath,saxon,xpath-2.0,Java,Xpath,Saxon,Xpath 2.0,我将Java与Saxon HE 9.4一起使用,因此我可以获得XPath 2.0支持 给定以下XML实例文档: <entities> <entity> <person> James </person> </entity> <entity> <legalEntity> ACME &
<entities>
<entity>
<person>
James
</person>
</entity>
<entity>
<legalEntity>
ACME
</legalEntity>
</entity>
</entities>
。。。正如所料
但是,逻辑分布在两个地方:XPath表达式本身和对getNodeName
方法的调用。我想要的是一个XPath表达式,它将返回一个通用的结果列表,我可以通过调用一些通用方法(而不是getNodeName
)来迭代这些结果
这样,所有逻辑都可以驻留在XPath表达式本身中,我的代码可以将XPath字符串保存在一个文件中,并在运行时处理它们以获得结果列表
尝试XPAth表达式/entities/entity/*/name()
只获取第一个值(person):
。。。如果我尝试将其强制转换为节点列表
,则代码会在运行时中断:
XPathExpression expr = xpath.compile("/entities/entity/*/name()");
NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
for (int i = 0 ; i < nodes.getLength() ; i++) {
...
XPathExpression expr=xpath.compile(“/entities/entity/*/name()”;
NodeList节点=(NodeList)expr.evaluate(doc,XPathConstants.NODESET);
对于(int i=0;i
(上述操作失败,原因是:net.sf.saxon.trans.XPathException:无法将XPath值转换为Java对象:必需的类是org.w3c.dom.NodeList;提供的值的类型为xs:string
)
那么,有没有一种通用的方法可以让XPath表达式计算结果列表(可以是元素标记、元素值、属性值和标记等),这样迭代这些结果的代码在所有情况下都是相同的,并且不必区分对
getNodeName()
或getNodeValue()的调用
?您正在使用XPath的JAXP接口。这是为XPath 1.0设计的,只识别XPath 1.0数据类型(字符串、节点集等)。您希望执行一个返回字符串列表(或者QName)的查询,因此您需要使用支持此类数据类型的API—具体来说,您需要转到Saxon的s9api
在s9api接口中,XPathSelector对象(请参阅)实现了Java的Iterable接口,因此您可以在Java“for each”指令中直接使用它,将结果作为XdmItem对象序列进行处理;XdmItem可以是节点或原子值,实际上是XPath 2.0数据模型中定义的任何类型
您可以使用s9api对任一Saxon的原生树模型(使用s9api DocumentBuilder构建)运行XPath表达式或者针对外部模型,如DOM、JDOM、XOM等。使用Saxon的本机模型比任何外部模型都快得多。根据:s9api也可用于免费的Saxon HE,这就是我正在使用的,但是我似乎找不到任何“官方”的、最新的源代码示例,使用该API的最新Saxon版本(9.5)您可以在saxon参考资料下载中找到示例程序:请参阅
element name = person
element name = legalEntity
XPathExpression expr = xpath.compile("/entities/entity/*/name()");
System.out.println("element name = "+expr.evaluate(doc));
XPathExpression expr = xpath.compile("/entities/entity/*/name()");
NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
for (int i = 0 ; i < nodes.getLength() ; i++) {
...