我有一个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的最后节点(包括其子节点)以及文件的其余部分,导致:
<a>
<b>
<e />
<f />
</b>
<c>
<g>
<j />
</g>
</c>
<d>
<h>
<i />
</h>
</d>
</a>
我对XSLT没有经验,非常感谢任何帮助。
答案 0 :(得分:2)
通常最好从identity transform开始并添加例外,然后有时会例外。
在此转换中,第一个模板是标识转换,第二个模板跳过<c>
和<d>
的子项,第三个模板覆盖排除项以包含每个<c>
的最后一个子项和<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以删除一些空格。根据{{3}},构造<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>
并且在这种情况下可能会有所改善。
哪个更好当然是品味问题。我发现原来的反应更清晰了。