XSL to return a node containing only children that match
If I have an XML node that looks like this
<node name="a">
<element ref="bb" />
<element ref="cc" />
<element ref="prefix_d开发者_高级运维d" />
<element ref="prefix_ee" />
</node>
I'd like to write an XSLT to return
<node name="a">
<element ref="prefix_dd" />
<element ref="prefix_ee" />
</node>
You can use the identity rule template and one single template to "cut-off" the unwanted elements.
Example:
<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="element[
not(
starts-with(@ref,'prefix_')
)
]"/>
</xsl:stylesheet>
Probably one of the shortest such transformations:
<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()[not(@ref[not(starts-with(.,'prefix_'))])]|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
When applied on the provided XML document:
<node name="a">
<element ref="bb" />
<element ref="cc" />
<element ref="prefix_dd" />
<element ref="prefix_ee" />
</node>
the wanted, correct result is produced:
<node name="a">
<element ref="prefix_dd"/>
<element ref="prefix_ee"/>
</node>
Explanation: Modified identity rule.
<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="/node">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="element[starts-with(@ref, 'prefix_')]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
精彩评论