使用 XML 标记在 Saxonica 中检索 XPath 结果

Retrieve XPath result in Saxonica with XML tag

我正在尝试使用来自 net.sf.saxonSaxonica API 的杂项 xpath 查询 XML 文件,但似乎每次查询操作 return 结果都没有 xml 标签 - 只有内容。有没有办法做到这一点(直接或变通)?

更明确地说:

对于 xml 文件

<books>
    <book lang="en">
        <nrpages>140</nrpages>
        <author>J.R.R.Tolkien</author>
    </book>
</books>

和 xpath

//book

我要取回

<book lang="en">
    <nrpages>140</nrpages>
    <author>J.R.R.Tolkien</author>
</book>

而不是

140
J.R.R.Tolkien

我尝试过的:

XPathFactory factory = new XPathFactoryImpl();
XPathExpression compiledXPath = factory.newXPath().compile(xPathExpression);
TinyNodeImpl nodeItem = (TinyNodeImpl) compiledXPath.evaluate(new InputSource(filename), XPathConstants.NODE);
nodeItem.atomize(); // brings only the content
nodeItem.getStrinValue(); // brings only the content

XPath表达式returns一个节点;您对节点所做的操作取决于调用应用程序代码。如果您调用 node.getStringValue(),您将获得 XPath 规范中定义的字符串值(即,与在 XPath 内的节点上调用 fn:string() 相同)。类似地,atomize() 方法遵循原子化的 XPath 规范(相当于 fn:data() 应用于节点。)

如果你希望节点被序列化为词法XML,有多种方法可以实现。如果您要使用 Saxon 的 s9api 接口而不是 JAXP 接口,我会推荐 XdmNode.toString()。使用 JAXP 接口然后转换为内部 Saxon 类 会给您带来两全其美的效果:您得到了 JAXP 的所有问题(例如弱类型,不支持 XPath 2.0)和 none 的好处(跨实现的可移植性)。但是,如果您更喜欢这样做,那么序列化 Saxon 节点的最简单方法可能就是静态方法 QueryResult.serialize(NodeInfo)。该方法的 3 参数版本使您可以完全控制序列化属性,例如缩进和添加 XML 声明。

对于 XPath 3.1,您还可以通过调用 fn:serialize() 在 XPath 表达式本身中调用序列化;这将避免在 Java 代码中使用任何撒克逊特有的 类 和方法。