我在 STX(XML 的流式转换)方面获得了很好的体验。基本上,它是 XSLT 的流式版本,非常适合以最少的内存占用解析大量数据。它有一个名为 Joost 的 Java 实现。
想出一个 STX 转换应该很容易,它忽略所有元素,直到元素匹配给定的 XPath,复制该元素及其所有子元素(使用模板组中的标识模板),并继续忽略元素直到下一场比赛。
更新
我拼凑了一个 STX 转换,可以满足我的理解。它主要依赖于仅 STX 的功能,例如模板组和可配置的默认模板。
<stx:transform xmlns:stx="http://stx.sourceforge.net/2002/ns"
version="1.0" pass-through="none" output-method="xml">
<stx:template match="element/child">
<stx:process-self group="copy" />
</stx:template>
<stx:group name="copy" pass-through="all">
</stx:group>
</stx:transform>
stx:transform 处的pass-through="none" 配置默认模板(用于节点、属性等)以不产生输出,但处理子元素。然后stx:template 匹配XPath element/child(这是放置匹配表达式的地方),它在“复制”组中“处理自我”,这意味着来自group name="copy" 的匹配模板在当前元素。该组具有pass-though="all",因此默认模板复制其输入并处理子元素。当element/child 元素结束时,控制权被传递回调用process-self 的模板,并再次忽略以下元素。直到模板再次匹配。
以下是一个示例输入文件:
<root>
<child attribute="no-parent, so no copy">
</child>
<element id="id1">
<child attribute="value1">
text1<b>bold</b>
</child>
</element>
<element id="id2">
<child attribute="value2">
text2
<x:childX xmlns:x="http://x.example.com/x">
<!-- comment -->
yet more<b i="i" x:i="x-i" ></b>
</x:childX>
</child>
</element>
</root>
这是对应的输出文件:
<?xml version="1.0" encoding="UTF-8"?>
<child attribute="value1">
text1<b>bold</b>
</child><child attribute="value2">
text2
<x:childX xmlns:x="http://x.example.com/x">
<!-- comment -->
yet more<b i="i" x:i="x-i" />
</x:childX>
</child>
不寻常的格式是跳过包含child 元素之外的换行符的文本节点的结果。