Reputation: 1682
I am trying to copy some descendant elements without a certain attribute. I cant figure out the right way to do this.
Here the file:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<itemlist>
<item>
<subitem id="g0b86bn6"/>
<subitem>
<subitem/>
<subitem id="8967698"/>
</subitem>
<subitem>
<subitem/>
<subitem id="9868966n7"/>
<subitem>
<subitem id="9896"/>
<subitem>
</subitem>
</item>
</itemlist>
The elements could be nested arbirtarily deep.
Expected output:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<itemlist>
<item>
<subitem>
<subitem/>
</subitem>
<subitem>
<subitem/>
</subitem>
</item>
</itemlist>
My xsl:
<xsl:template match="item">
<xsl:for-each select="child::*">
<xsl:if test=".[not(@id)]">
<xsl:copy>
<xsl:apply-templates select=". | @*"/>
</xsl:copy>
</xsl:if>
</xsl:for-each>
</xsl:template>
The problem: It only copies the children, not the descendants. And copy-of also copies the descendants that I dont want to copy.
How should I do this? Thanks for help and tips!
Upvotes: 0
Views: 832
Reputation: 116993
The preferred strategy in cases like these is to use the identity transform template to copy everything as is, then add exception templates to suppress nodes you do not want to be passed to the output. For example, the following stylesheet:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="subitem[@id]"/>
</xsl:stylesheet>
when applied to the following well-formed input:
XML
<itemlist>
<item>
<subitem id="g0b86bn6"/>
<subitem>
<subitem/>
<subitem id="8967698"/>
</subitem>
<subitem>
<subitem/>
<subitem id="9868966n7"/>
<subitem>
<subitem id="9896"/>
</subitem>
</subitem>
</item>
</itemlist>
will suppress any subitem
element that has an id
attribute, resulting in:
Output
<?xml version="1.0" encoding="utf-8"?>
<itemlist>
<item>
<subitem>
<subitem/>
</subitem>
<subitem>
<subitem/>
<subitem/>
</subitem>
</item>
</itemlist>
Upvotes: 2