我曾使用
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>
pass-through="none"
在
stx:transform
中配置默认模板(用于节点、属性等)不产生输出,但处理子元素。然后
stx:template
匹配XPath
element/child
(这是您放置匹配表达式的位置),它在“copy”组中“处理自身”,这意味着当前元素上调用了来自
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">
yet more<b i="i" x:i="x-i" />
</x:childX>
</child>
这种不寻常的格式是由于跳过包含换行符的文本节点而产生的,这些节点在
child
元素之外。