我有XML文件,我想按原样复制它,但我想过滤一些不需要的元素和属性,例如以下是原始文件:
<root>
<e1 att="test1" att2="test2"> Value</e1>
<e2 att="test1" att2="test2"> Value 2 <inner class='i'>inner</inner></e2>
<e3 att="test1" att2="test2"> Value 3</e3>
</root>
过滤后( e3 元素和 att2 属性已删除):
<root>
<e1 att="test1" > Value</e1>
<e2 att="test1" > Value 2 <inner class='i'>inner</inner></e2>
</root>
备注:
谢谢
答案 0 :(得分:9)
我知道您更愿意使用for-each
,但为什么不使用身份转换,然后使用您不想保留的内容覆盖该模板?
此样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="e3|@att2"/>
</xsl:stylesheet>
产生
<root>
<e1 att="test1"> Value</e1>
<e2 att="test1"> Value 2 <inner class="i">inner</inner>
</e2>
</root>
答案 1 :(得分:1)
正如@DevNull向您展示的那样,使用身份变换更容易,更简洁。无论如何,这是一个可能的解决方案for-each
,而不是apply-templates
,如您所要求的那样:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/root">
<root>
<xsl:for-each select="child::node()">
<xsl:choose>
<xsl:when test="position()=last()-1"/>
<xsl:otherwise>
<xsl:copy>
<xsl:copy-of select="@att"/>
<xsl:copy-of select="child::node()"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</root>
</xsl:template>
关于使用身份转换的注意事项
如果您的情况确实如此,我的意思是未知的元素名称,@ DevNull将不起作用,您需要更一般的东西:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root/child::node()[position()=last()]|@att2"/>
</xsl:stylesheet>
此解决方案即使使用最后一个元素e4
或e1000
也可以使用。