Hi I had performed a transformation which drops a tag if it is null.
I wanted to check whether my transformation is working fine, so instead of checking it manually, I wrote one more XSLT code which just checks the presence of that particular tag in the OUTPUT XML, if it is null, then the second XSLT should output a text "FOUND". (I don't actually need some XML kind of output but I am just using XSLT for searching.)
When I tried with this XSL code ::
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/SiebelMessage//SuppressCalendar[.!='']">
FOUND
</xsl:template>
</xsl:stylesheet>
It outputs all the TEXT DATA that is present in the XML file,
to avoid that, I had to write this code::
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/SiebelMessage//SuppressCalendar[.!='']">
FOUND
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
why did the former code outputs TEXT, why should I insist XSL to ignore all other text? is that the behavior of all XML parsers or only of my own (I am using msxml parser).
You are discovering one of the most fundamental XSLT features as specified in the Specification: the built-in templates of XSLT.
From the Spec:
So, the reported behavior is the result of the application of the built-in templates -- the 1st and 2nd of all three of them.
It is a good XSLT design pattern to override the built-in templates with your own that will issue an error message whenever called so that the programmer immediately knows his transformation is "leaking":
For example, if there is this XML document:
and it is processed with this transformation:
the result is:
and the programmer will be greatly confused how the unwanted text appeared.
However, just adding this
catch-all template
helps avoid any such confusion and catch errors immediately:Now, besides the confusing output the programmer gets a warning that explains the problem immediately:
Later Addition by Michael Kay for XSLT 3.0
In XSLT 3.0, rather than adding a catch-all template rule, you can specify the fallback behaviour on an
xsl:mode
declaration. For example,<xsl:mode on-no-match="shallow-skip"/>
causes all nodes that are not matched (including text nodes) to be skipped, while<xsl:mode on-no-match="fail"/>
treats a no-match as an error, and<xsl:mode warning-on-no-match="true"/>
results in a warning.There are several built in template rules in XSL, one of which is this:
It outputs text.