Forum Moderators: open
<topNode>
<midNode foo="" bar="2">
<midNode>
<midNode foo="1" bar="">
</midNode>
</topNode>
I tried this: <xsl:template match="@*[.='']"/>
but that killed the entire output for me, not just empty attributes
Any suggestions?
Thanks
Mark
The template
<xsl:template match="*[@*='']/>
will select any node (with any name) with at least one attribute (with any name) that is a string with zero length. Although within this template, you still have to figure out which of the attributes not to copy (because they are empty) and which to copy.
So it might be better to select all nodes and test all attributes as in the stylesheet below.
This will not select attributes which contain whitespace only. To remove these you could use
<xsl:if test="normalize-space(.)"
which will convert the node to a string and remove leading/trailing whitespace,
instead of
<xsl:if test=".=''">
Furthermore, if all attributes of a certain node are empty, you will end up with an empty node. This might or might not be what you want.
On your road to enlightenment you perhaps will want to try the following stylesheet on any xml:
<?xml version="1.0" encoding="iso8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html"/><xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="*">
<br/>
<xsl:text>(Start </xsl:text>
<xsl:value-of select='name()'/>
<xsl:text>) </xsl:text>
<xsl:for-each select="@*">
<!-- 'empty' attributes -->
<xsl:if test=".=''">
<xsl:value-of select='name()'/>
<xsl:text>=</xsl:text>
<xsl:text>empty </xsl:text>
</xsl:if>
<!-- 'non-empty' attributes -->
<xsl:if test="not(.='')">
<xsl:value-of select='name()'/>
<xsl:text>=</xsl:text>
<xsl:value-of select='.'/>
</xsl:if>
</xsl:for-each>
<xsl:apply-templates/>
<xsl:text> (End </xsl:text>
<xsl:value-of select='name()'/>
<xsl:text>)</xsl:text>
</xsl:template>
</xsl:stylesheet>
I employed the following:
<xsl:variable name="Foo"><xsl:value-of select="normalize-space(@c2)"/></xsl:variable> Then later in my template:
<xsl:if test="string-length($Foo) > 0">
<xsl:attribute name="iFoo"><xsl:value-of select="$Foo"/></xsl:attribute>
</xsl:if>
and it works like a charm. Perhaps there is still a better way? In any case, this is more than adequate.
Thanks again!
Mark