Reputation: 51
I'm doing an XSLT Transformation and I want to ignore elements that have a value of zero as well as elements that are blank. A sample of the XML I am using is shown below
<row>
<col1>a</col1>
<col2></col2>
<col3>0</col3>
</row>
For example, I have tried using:
<xsl:if test="col2 != '0' or col2 != ' '><xsl:value-of select="col2"/></xsl:if>
but it to filter out everything instead of just filtering the data that are blank or zero. But this doesn't work. What am I doing incorrectly?
Upvotes: 0
Views: 2240
Reputation: 640
You can also try out this one
<xsl:for-each select="row/*">
<xsl:if test="normalize-space(.)!=''">
<xsl:if test=".!='0'">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:if>
</xsl:for-each>
Upvotes: 0
Reputation: 116982
Your test is a classic tautology: x!=a or x!=b is always true, because when x=a then the second proposition is true, when x=b then the first proposition is true, and when x=c, both are true. In terms of logic, you need to write x!=a AND x!=b.
In terms of XSLT, if col2 is supposed to be a non-zero numeric value, you could formulate your test as:
<xsl:if test="number(col2)">
I am not sure in what context you are testing this; usually it's best to eliminate the unwanted elements before having to deal with them, for example by:
<xsl:apply-templates select="col2[boolean(number(.))]"/>
Upvotes: 1
Reputation: 70608
What you are doing incorrectly is that you are using an or
instead of an and
. Additionally, you are also checking for a single space, not an empty element. So, if you consider spaces as 'blanks' you should use the normalize-space
function
<xsl:if test="col2 != '0' and normalize-space(col2) != ''">
Note, depending on what you are actually trying to achieve, it may probably be better to use template matching here, instead of xsl:if
Try this for example
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes" />
<xsl:template match="row">
<xsl:copy>
<xsl:apply-templates select="*[. != '0' and normalize-space(.) != '']" />
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Alternatively, you can use a 'pull' approach, and write template to ignore empty elements (as opposed to specifically selecting the ones you want to copy). This would also work
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes" />
<xsl:template match="row/*[. = '0' or normalize-space(.) = '']" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1