如何从NodeInfo创建xPath语句?

时间:2015-11-30 18:17:10

标签: java xml xpath saxon

我使用S9API和Saxon 9.7 HE,我有一个NodeInfo对象。我需要创建一个唯一对应于此NodeInfo的xPath语句。获取前缀,节点名称和父级是很容易的:

String prefix = node.getPrefix();
String localPart = node.getLocalPart();
NodeInfo parent = node.getParent();

所以我可以走上树,在我走的时候建立xPath。但我无法找到的是获取位置谓词信息的任何方法。 IOW,它不足以创建:

/persons/person/child

因为它可能匹配多个子元素。我需要创建:

/persons/person[2]/child[1]

只匹配一个子元素。有关如何获取位置谓词信息的任何想法?或者可能有更好的方法来完成这项工作?

BTW,对于那些使用通用DOM而不是S9API的人来说,这是解决这个问题的简单方法:http://practicalxml.sourceforge.net/apidocs/net/sf/practicalxml/DomUtil.html#getAbsolutePath(org.w3c.dom.Element)

编辑:@Michael Kay的回答有效。添加一些肉:

XPathExpression xPathExpression = xPath.compile("./path()");
List matches = (List) xPathExpression.evaluate(node, XPathConstants.NODESET);
String pathToNode = matches.get(0).toString();
// If you want to remove the expanded QName syntax:
pathToNode = pathToNode.replaceAll("Q\\{.*?\\}", "");

必须使用先前用于获取NodeInfo对象的相同xPath对象来完成此操作。

1 个答案:

答案 0 :(得分:2)

在XPath 3.0中,您可以使用fn:path()。

早期的Saxon发行版提供了saxon:path()。

这里的挑战是处理命名空间。 fn:path()通过使用新的extended-QName语法返回对命名空间前缀绑定不敏感的路径

/Q{}persons/Q{}person[2]/Q{}child[1]