使用 XSLT 删除除 last 之外的所有子节点
Remove all child nodes except last using XSLT
我有一个 XML 文件:
<a>
<b>
<e />
<f />
</b>
<c>
<g>
<j />
</g>
<g>
<j />
</g>
<g>
<j />
</g>
</c>
<d>
<h>
<i />
</h>
<h>
<i />
</h>
<h>
<i />
</h>
</d>
</a>
我想做的是将 XSL 转换应用于 仅 获取 c 和 d 的 last 节点(包括它们的子节点)以及文件的其余部分,导致:
<a>
<b>
<e />
<f />
</b>
<c>
<g>
<j />
</g>
</c>
<d>
<h>
<i />
</h>
</d>
</a>
我没有使用 XSLT 的经验,非常感谢任何帮助。
通常最好从 identity transform 开始并添加例外,然后有时例外的例外。
在此转换中,第一个模板是身份转换,第二个模板跳过 <c>
和 <d>
的子级,第三个覆盖排除以包含每个 [=12] 的最后一个子级=] 和 <d>
标签。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="c/*|d/*"/>
<xsl:template match="c/*[last()]|d/*[last()]">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我必须修改您的输入 xml 以删除一些空格。根据 specification (section 3.1 Start-tags, end-tags, and empty-element tags).
,构造 <x/ >
并不是真正有效的
如评论中所述,除了标识外,仅使用一个模板即可缩短此时间。我无法让 [not(last()]
工作,但这个较短的模板可以:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="c/*[position() < last()]|d/*[position() < last()]"/>
</xsl:stylesheet>
而且病情可能会有改善。
哪个更好当然是口味问题。我发现我原来的回复稍微清楚了。
我有一个 XML 文件:
<a>
<b>
<e />
<f />
</b>
<c>
<g>
<j />
</g>
<g>
<j />
</g>
<g>
<j />
</g>
</c>
<d>
<h>
<i />
</h>
<h>
<i />
</h>
<h>
<i />
</h>
</d>
</a>
我想做的是将 XSL 转换应用于 仅 获取 c 和 d 的 last 节点(包括它们的子节点)以及文件的其余部分,导致:
<a>
<b>
<e />
<f />
</b>
<c>
<g>
<j />
</g>
</c>
<d>
<h>
<i />
</h>
</d>
</a>
我没有使用 XSLT 的经验,非常感谢任何帮助。
通常最好从 identity transform 开始并添加例外,然后有时例外的例外。
在此转换中,第一个模板是身份转换,第二个模板跳过 <c>
和 <d>
的子级,第三个覆盖排除以包含每个 [=12] 的最后一个子级=] 和 <d>
标签。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="c/*|d/*"/>
<xsl:template match="c/*[last()]|d/*[last()]">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我必须修改您的输入 xml 以删除一些空格。根据 specification (section 3.1 Start-tags, end-tags, and empty-element tags).
,构造<x/ >
并不是真正有效的
如评论中所述,除了标识外,仅使用一个模板即可缩短此时间。我无法让 [not(last()]
工作,但这个较短的模板可以:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="c/*[position() < last()]|d/*[position() < last()]"/>
</xsl:stylesheet>
而且病情可能会有改善。
哪个更好当然是口味问题。我发现我原来的回复稍微清楚了。