Re: [xsl] position()!=last() works in one env, not in another

Subject: Re: [xsl] position()!=last() works in one env, not in another
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Tue, 06 Feb 2007 21:02:11 -0800
At 2007-02-06 23:43 -0500, Sam Carleton wrote:
I am testing in Altova XMLSpy and running in PHP5.  In XMLSpy the
position()!=last() works fine, but in PHP5, it is always true.  Here
is the code:

<xsl:template match="p:category|p:subCategory|p:imageDir" mode="menu">
<xsl:when test="@objectID=$objectID"><xsl:value-of select="@name"/></xsl:when>
<xsl:otherwise><a href="{$self}?fldoid={@objectID}"><xsl:value-of
<xsl:if test="position()!=last()"><xsl:text

Does anyone know if PHP5 (Libxslt) has any issues with this test:

<xsl:if test="position()!=last()">

You don't show enough of the code to tell.

For example, if your data were:


And you did:


... with the following match:

<xsl:template match="c">
 <xsl:if test="position()!=last()">

Then it would return true() because the last node child of <test> is a text node. Perhaps you are doing something similar.

Why would XMLSpy return true()? Perhaps it is incorrectly throwing away white-space-only text nodes and thinks that the last node child of <test> is <c/>, which it isn't. For example, you would get the same incorrect result using Internet Explorer, since it has a bug that throws away white-space-only text nodes. If XMLSpy is using msxml.dll the same way that Internet Explorer is using it, then you will get non-conformant behaviour.

Having a sample of only two tools, each one doing something different, does not tell you which one is wrong. I suspect libxslt is correct and XMLSpy is wrong ... have you tested your stylesheet with Saxon?

And, you are using *very* bad form with disable-output-escaping="yes" ... that is *not* the use case for which the attribute is defined. You should be using one of the two following methods of getting what you need:

(1) - numeric character reference:

  <xsl:if test="position()!=last()">&#xa0;|&#xa0;</xsl:if>
  <xsl:if test="position()!=last()">&#160;|&#160;</xsl:if>

(2) - entity reference:

<!DOCTYPE xsl:stylesheet [
<!ENTITY nbsp "&#160;"> <!--known for HTML output, not in XML-->
<xsl:stylesheet xmlns:xsl="";
  <xsl:if test="position()!=last()">&nbsp;|&nbsp;</xsl:if>

When one incorrectly composes markup by using disable-output-escaping="yes", the serialized result tree happens to be correct, but the abstract result tree is not. For this reason, one should not use this approach to compose markup that can be validly created using appropriate mechanisms.

I hope this helps.

. . . . . . . . . . Ken

World-wide corporate, govt. & user group XML, XSL and UBL training
RSS feeds:     publicly-available developer resources and training
G. Ken Holman                 mailto:gkholman@xxxxxxxxxxxxxxxxxxxx
Crane Softwrights Ltd.
Box 266, Kars, Ontario CANADA K0A-2E0    +1(613)489-0999 (F:-0995)
Male Cancer Awareness Aug'05
Legal business disclaimers:

Current Thread