This problem appears to be present in Saxon 8.0 but not in Saxon 8.1
 
(I think the problem was that path expressions in a function were being "analyzed" twice, and the order of the results of the ancestor axis was therefore being flipped twice. I found the problem during Saxon 8.1 development when changing templates to use the same code as functions).
 
Michael Kay
http://www.saxonica.com/


From: saxon-help-admin@lists.sourceforge.net [mailto:saxon-help-admin@lists.sourceforge.net] On Behalf Of Andre Cusson
Sent: 30 September 2004 03:39
To: saxon-help@lists.sourceforge.net
Subject: [saxon] function reverse of template ?

Hi,

I was surprise to see that the same code produces reverse results whether it is in a function or in a template and I am not sure why yet.  Apart from the fact that the function version also requires the context to be passed as a parameter, as well as 2 extra enclosing layers of <xsl:value-of> to avoid additional spaces, I would have expected <template match="page" mode="build"> and function zz:build to output the same results, but the ancestor-or-self order seems to be flipped.  I must have missed something. What do you think ?

incoming XML :

<page title="A">
        <page title="B">
                <page title="C">
                        <page title="D"/>
                </page>
        </page>
</page>


processing stylesheet :


<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
        xmlns:xsl
="http://www.w3.org/1999/XSL/Transform"
        xmlns:xs
="http://www.w3.org/2001/XMLSchema"
        xmlns:xfn
="http://www.w3.org/2003/11/xpath-functions"
        xmlns:zz="http://www.xxx.com/zz"
        exclude-result-prefixes
="xsl xs xfn zz"
        >

        <xsl:output method="xml" version="1.0" omit-xml-declaration="yes" encoding="UTF-8" indent="no"/>

        <xsl:variable name="dir">/</xsl:variable>
        
        
<xsl:template match="/">
                <xsl:message><xsl:value-of select="zz:build(//page[@title = 'D'])"/></xsl:message>
                <xsl:message><xsl:apply-templates mode="build" select="//page[@title = 'D']"/></xsl:message>
        </xsl:template>
        
        
<xsl:template match="page" mode="build">
                <xsl:variable name="ancestors" select="ancestor-or-self::page/@title"/>
                <xsl:variable name="levels" select="count($ancestors)"/>
                <xsl:for-each select="1 to $levels">
                        <xsl:value-of select="for $i in 1 to . return $ancestors[$i]" separator="_"/>
                        <xsl:if test=". &lt; $levels"><xsl:value-of select="$dir"/></xsl:if>
                </xsl:for-each>
        </xsl:template>
        
        
<xsl:function name="zz:build">
                <xsl:param name="context"/>
                <xsl:variable name="ancestors" select="$context/ancestor-or-self::page/@title"/>
                <xsl:variable name="levels" select="count($ancestors)"/>
                <xsl:value-of>
                        <xsl:for-each select="1 to $levels">
                                <xsl:value-of>
                                        <xsl:value-of select="for $i in 1 to . return $ancestors[$i]" separator="_"/>
                                        <xsl:if test=". &lt; $levels"><xsl:value-of select="$dir"/></xsl:if>
                                </xsl:value-of>
                        </xsl:for-each>
                </xsl:value-of>
        </xsl:function>
        
</xsl:stylesheet>

        
result output:

A/A_B/A_B_C/A_B_C_D
D/D_C/D_C_B/D_C_B_A


Thank you,
ac