Re: [xsl] saxon xmlspy discrepancy in whitespace handling

Subject: Re: [xsl] saxon xmlspy discrepancy in whitespace handling
From: Abel Braaksma <abel.online@xxxxxxxxx>
Date: Wed, 17 Jan 2007 11:46:44 +0100
Hi Erwin,

The default template is what's bugging you, and XML spy is showing how not to do it.

See my comments about your XSLT file below, and you should be safe.

Alternatively (though I'd advice against it) you can call Saxon with the -sall option to strip all whitespace of the source before it is being processed.

Erwin Kloeck wrote:
xmlns:fo="http://www.w3.org/1999/XSL/Format";
xmlns:xs="http://www.w3.org/2001/XMLSchema";
xmlns:fn="http://www.w3.org/2005/xpath-functions";
xmlns:xdt="http://www.w3.org/2005/xpath-datatypes";

you don't seem to use these namespaces in your source. It won't harm to leave them, it won't harm to leave them out either.


<xsl:output method="text" version="1.0" encoding="iso-8859-1" />

Note that the source XML may contain characters that do not fit in 8859-1. In which case Saxon will throw the error "Output character not available in this encoding".


<xsl:variable name="newline"><xsl:text>&#10;</xsl:text></xsl:variable>

This can also be written as follows, but that is a matter of taste: <xsl:variable name="newline">&#10;</xsl:variable> or <xsl:variable name="newline" select=" '&#10;' " />

  <xsl:template match="/">
      <xsl:apply-templates />
  </xsl:template>

This is where the danger starts. You apply all templates here (well, all default templates), from the root. This means that if you do not apply specific matches for each node (here: 'top' is the missing node with your matches,), the default template (i.e.: value-of) is used for these nodes (resulting in outputting whitespace text from the 'top' node) .


It is safer to explicitly tell XSLT what you want to select. The following only selects the nodes you want to process:

<xsl:template match="/">
  <xsl:apply-templates select="top/section" />
<xsl:template>

  <xsl:template match="//section" >
      <xsl:call-template name="section-header" />
 </xsl:template>

It is not recommended to start a match with "//". It is not needed either. The following template match would suffice:


<xsl:template match="section" >
.....

 <xsl:template name="section-header" >
     <xsl:value-of select="@name"/>
     <xsl:value-of select="$newline"/>
 </xsl:template>

Well, you may have a reason to call a named template, I don't know how your original project looks like. However, in this case, both the template match and the named template can be combined as follows:


<xsl:template match="section" >
   <xsl:value-of select="@name" />
   <xsl:value-of select="$newline"/>
</xsl:template>

Also note that using a named template and the current axis (you select '@name' attribute from the current axis), makes it impossible to use the named template in any other context than where you need this newline and the @name. It is often better to use a named template with parameters and not rely on the context (or supply the context node by parameter). The latter is illustrated in the following example:

<xsl:template match="section" >
  <xsl:call-template name="section-header">
     <xsl:with-param select="current()" />
  </xsl:call-template>
</xsl:template>

<xsl:template name="section-header" >
  <xsl:param name="current-node" />
  <xsl:value-of select="$current-node/@name"/>
  <xsl:value-of select="$newline"/>
</xsl:template>


Put is altogether and your whole xslt stylesheet may look as follows, producing the output you want on either processor:


<xsl:stylesheet version="2.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; >

<xsl:output method="text" encoding="ISO-8859-1" />
<xsl:variable name="newline" select=" '&#10;' " />


  <xsl:template match="/">
    <xsl:apply-templates select="top/section" />
  </xsl:template>


<xsl:template match="section" > <xsl:value-of select="@name" /> <xsl:value-of select="$newline"/> </xsl:template>

</xsl:stylesheet>


P.S: I have long given up on using XML Spy because of its lack of reliability in regards to the specs. I have forgotten about all the reasons, but in your post you illustrate exactly why you should avoid relying on it too much.


Cheers,
-- Abel Braaksma
  http://www.nuntia.nl

Current Thread