如何从 NodeInfo 创建 xPath 语句?

How do I create an xPath statement from a NodeInfo?

我在 Saxon 9.7 HE 中使用 S9API,并且我有一个 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]

这将只匹配一个子元素。关于如何获取位置谓词信息的任何想法?或者也许有更好的方法来完全做到这一点?

顺便说一句,对于那些使用通用 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 对象来完成。

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

较早的 Saxon 发布报价 saxon:path()。

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

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