Reputation: 33
I am trying to filter an xml document for leaf elements that contain a specific attribute but I would like to keep the higher level document in tact. And I would like to do this with XSLT.
The document to begin with looks like this:
<root>
<a name="foo">
<b name="bar" critical="yes"/>
</a>
<a name="foo2" critical="yes">
<b name="bar2">
<b name="bar3">
</a>
<a name="foo3">
<b name="bar4">
<b name="bar5">
</a>
</root>
The result should look like this:
<root>
<a name="foo">
<b name="bar" critical="yes"/>
</a>
<a name="foo2" critical="yes">
</a>
</root>
Since XSLT is not my native language, any help is very appreciated.
Upvotes: 3
Views: 77
Reputation: 243479
This transformation:
<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="*[not(descendant-or-self::*[@critical='yes'])]"/>
</xsl:stylesheet>
when applied on the provided XML document (corrected for well-formedness):
<root>
<a name="foo">
<b name="bar" critical="yes"/>
</a>
<a name="foo2" critical="yes">
<b name="bar2"/>
<b name="bar3"/>
</a>
<a name="foo3">
<b name="bar4"/>
<b name="bar5"/>
</a>
</root>
produces the wanted, correct result:
<root>
<a name="foo">
<b name="bar" critical="yes"/>
</a>
<a name="foo2" critical="yes"/>
</root>
Upvotes: 1