Problem with passing variables during a recursion

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Problem with passing variables during a recursion

Bugzilla from krissn@op.pl
I've been working on a quite complex stylesheet with nested recursions and  
I encountered a rather serious problem.
Inside a recursion I use a variable to transfer a list of elements between  
template calls. This list is extended by one or more elements in each call  
and the new, extended variable is passed to the next template call. The  
appending of elements is made by declaring another variable, copying the  
contents of the list using xsl:copy-of and finally appending some elements  
to the end. At the end of the recursion the variable contents are printed  
out (in fact they land in another variable, but I think that's not the key  
to the problem).
If I use Saxon 8.4 to process this stylesheet, the result is a complete  
list. But when using Saxon 8.5 or 8.5.1 the output contains only the first  
element.

Here is a sample stylesheet reproducing the problem:

<?xml version="1.0" encoding="utf-8"?>

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

        <xsl:output indent="yes" />

        <xsl:template name="test">
                <xsl:param name="count" select="10" />
                <xsl:param name="result" />

                <xsl:choose>
                        <xsl:when test="$count &gt; 0">

                                <xsl:call-template name="test">
                                        <xsl:with-param name="count" select="$count - 1" />
                                        <xsl:with-param name="result">

                                                <!-- This is the place where the list is extended -->
                                                <!-- by one element. -->
                                                <xsl:copy-of select="$result" />
                                                <test1><xsl:value-of select="$count" /></test1>

                                        </xsl:with-param>
                                </xsl:call-template>
                        </xsl:when>
                        <xsl:otherwise>
                                <testtest>
                                        <xsl:copy-of select="$result" />
                                </testtest>
                        </xsl:otherwise>
                </xsl:choose>
        </xsl:template>

        <xsl:template match="/">
                <xsl:call-template name="test" />
        </xsl:template>
</xsl:stylesheet>

Using Saxon 8.4 gives the correct output:

<?xml version="1.0" encoding="UTF-8"?>
<testtest>
    <test1>10</test1>
    <test1>9</test1>
    <test1>8</test1>
    <test1>7</test1>
    <test1>6</test1>
    <test1>5</test1>
    <test1>4</test1>
    <test1>3</test1>
    <test1>2</test1>
    <test1>1</test1>
</testtest>

Using Saxon 8.5 gives only this:

<?xml version="1.0" encoding="UTF-8"?>
<testtest>
    <test1>10</test1>
</testtest>

After putting copy-of AFTER the added element:

<test1><xsl:value-of select="$count" /></test1>
<xsl:copy-of select="$result" />

the result is correct:

<?xml version="1.0" encoding="UTF-8"?>
<testtest>
    <test1>1</test1>
    <test1>2</test1>
    <test1>3</test1>
    <test1>4</test1>
    <test1>5</test1>
    <test1>6</test1>
    <test1>7</test1>
    <test1>8</test1>
    <test1>9</test1>
    <test1>10</test1>
</testtest>

I would like to know if this is indeed a bug in Saxon 8.5 or am I doing  
something wrong.
I'd appreciate any help.

Krzysztof Nowicki


-------------------------------------------------------
SF.Net email is Sponsored by the Better Software Conference & EXPO
September 19-22, 2005 * San Francisco, CA * Development Lifecycle Practices
Agile & Plan-Driven Development * Managing Projects & Teams * Testing & QA
Security * Process Improvement & Measurement * http://www.sqe.com/bsce5sf
_______________________________________________
saxon-help mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/saxon-help
Reply | Threaded
Open this post in threaded view
|

RE: Problem with passing variables during a recursion

Michael Kay
Thanks, yes, it's certainly a nasty problem. I've worked out what's
happening: I haven't got a fix yet, because it's in an area where fixing
this problem could easily break other things. In fact, the bug seems to have
been introduced as a result of an inadequate fix to other problems in this
area. The bug can be described thus:

When a document node is present in the sequence constructor used to
construct the children of a new document node, any element nodes that follow
that document node in the sequence constructor are not attached properly to
the new tree, so an iteration over the children of the new document node
will not find them.

[The data is actually all there in the tree, but a pointer has been set
incorrectly, so it's not being found]

There's an easy circumvention though:

(a) in line 10 make the default value of the $result parameter an empty
sequence rather than an empty string:

                <xsl:param name="result" select="()"/>

(b) in line 21, copy the document element of $result rather than the
document node itself:

            <xsl:copy-of select="$result/*" />

I hope that helps you move forwards.

(the reason for (a) is that without it, $result/* reports a type error on
the first iteration).

Michael Kay
http://www.saxonica.com/



> -----Original Message-----
> From: [hidden email]
> [mailto:[hidden email]] On Behalf Of Kriss
> Sent: 13 September 2005 17:10
> To: [hidden email]
> Subject: [saxon] Problem with passing variables during a recursion
>
> I've been working on a quite complex stylesheet with nested
> recursions and  
> I encountered a rather serious problem.
> Inside a recursion I use a variable to transfer a list of
> elements between  
> template calls. This list is extended by one or more elements
> in each call  
> and the new, extended variable is passed to the next template
> call. The  
> appending of elements is made by declaring another variable,
> copying the  
> contents of the list using xsl:copy-of and finally appending
> some elements  
> to the end. At the end of the recursion the variable contents
> are printed  
> out (in fact they land in another variable, but I think
> that's not the key  
> to the problem).
> If I use Saxon 8.4 to process this stylesheet, the result is
> a complete  
> list. But when using Saxon 8.5 or 8.5.1 the output contains
> only the first  
> element.
>
> Here is a sample stylesheet reproducing the problem:
>
> <?xml version="1.0" encoding="utf-8"?>
>
> <xsl:stylesheet version="2.0"  
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
>
> <xsl:output indent="yes" />
>
> <xsl:template name="test">
> <xsl:param name="count" select="10" />
> <xsl:param name="result" />
>
> <xsl:choose>
> <xsl:when test="$count &gt; 0">
>
> <xsl:call-template name="test">
> <xsl:with-param
> name="count" select="$count - 1" />
> <xsl:with-param name="result">
>
> <!-- This is
> the place where the list is extended -->
> <!-- by one element. -->
> <xsl:copy-of
> select="$result" />
>
> <test1><xsl:value-of select="$count" /></test1>
>
> </xsl:with-param>
> </xsl:call-template>
> </xsl:when>
> <xsl:otherwise>
> <testtest>
> <xsl:copy-of select="$result" />
> </testtest>
> </xsl:otherwise>
> </xsl:choose>
> </xsl:template>
>
> <xsl:template match="/">
> <xsl:call-template name="test" />
> </xsl:template>
> </xsl:stylesheet>
>
> Using Saxon 8.4 gives the correct output:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <testtest>
>     <test1>10</test1>
>     <test1>9</test1>
>     <test1>8</test1>
>     <test1>7</test1>
>     <test1>6</test1>
>     <test1>5</test1>
>     <test1>4</test1>
>     <test1>3</test1>
>     <test1>2</test1>
>     <test1>1</test1>
> </testtest>
>
> Using Saxon 8.5 gives only this:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <testtest>
>     <test1>10</test1>
> </testtest>
>
> After putting copy-of AFTER the added element:
>
> <test1><xsl:value-of select="$count" /></test1>
> <xsl:copy-of select="$result" />
>
> the result is correct:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <testtest>
>     <test1>1</test1>
>     <test1>2</test1>
>     <test1>3</test1>
>     <test1>4</test1>
>     <test1>5</test1>
>     <test1>6</test1>
>     <test1>7</test1>
>     <test1>8</test1>
>     <test1>9</test1>
>     <test1>10</test1>
> </testtest>
>
> I would like to know if this is indeed a bug in Saxon 8.5 or
> am I doing  
> something wrong.
> I'd appreciate any help.
>
> Krzysztof Nowicki
>
>
> -------------------------------------------------------
> SF.Net email is Sponsored by the Better Software Conference & EXPO
> September 19-22, 2005 * San Francisco, CA * Development
> Lifecycle Practices
> Agile & Plan-Driven Development * Managing Projects & Teams *
> Testing & QA
> Security * Process Improvement & Measurement *
> http://www.sqe.com/bsce5sf
> _______________________________________________
> saxon-help mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/saxon-help
>




-------------------------------------------------------
SF.Net email is sponsored by:
Tame your development challenges with Apache's Geronimo App Server. Download
it for free - -and be entered to win a 42" plasma tv or your very own
Sony(tm)PSP.  Click here to play: http://sourceforge.net/geronimo.php
_______________________________________________
saxon-help mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/saxon-help
Reply | Threaded
Open this post in threaded view
|

RE: Problem with passing variables during a recursion

Michael Kay
In reply to this post by Bugzilla from krissn@op.pl

By the way, an observation on this. I don't know what the full stylesheet
looks like, but it's probably better for your recursive call to construct a
sequence rather than a new tree. You probably don't really need to do the
expensive xsl:copy-of operation:

<xsl:with-param name="result" as="element()">
  <xsl:sequence select="$result"/>
  <test1><xsl:value-of select="xxxx"/></test1>
</xsl:with-param>

This should give much better performance. Also, as a result of discussion on
this list last week with Dimitre Novatchev, this construct should benefit
from further optimisations in the next release. (At present Saxon copies the
list of references to the nodes, which is already much better than making a
deep copy of the nodes. In future it won't even copy the list of references,
it will simply reuse the same list.)

Michael Kay
 

> -----Original Message-----
> From: [hidden email]
> [mailto:[hidden email]] On Behalf Of Kriss
> Sent: 13 September 2005 17:10
> To: [hidden email]
> Subject: [saxon] Problem with passing variables during a recursion
>
> I've been working on a quite complex stylesheet with nested
> recursions and  
> I encountered a rather serious problem.
> Inside a recursion I use a variable to transfer a list of
> elements between  
> template calls. This list is extended by one or more elements
> in each call  
> and the new, extended variable is passed to the next template
> call. The  
> appending of elements is made by declaring another variable,
> copying the  
> contents of the list using xsl:copy-of and finally appending
> some elements  
> to the end. At the end of the recursion the variable contents
> are printed  
> out (in fact they land in another variable, but I think
> that's not the key  
> to the problem).
> If I use Saxon 8.4 to process this stylesheet, the result is
> a complete  
> list. But when using Saxon 8.5 or 8.5.1 the output contains
> only the first  
> element.
>
> Here is a sample stylesheet reproducing the problem:
>
> <?xml version="1.0" encoding="utf-8"?>
>
> <xsl:stylesheet version="2.0"  
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
>
> <xsl:output indent="yes" />
>
> <xsl:template name="test">
> <xsl:param name="count" select="10" />
> <xsl:param name="result" />
>
> <xsl:choose>
> <xsl:when test="$count &gt; 0">
>
> <xsl:call-template name="test">
> <xsl:with-param
> name="count" select="$count - 1" />
> <xsl:with-param name="result">
>
> <!-- This is
> the place where the list is extended -->
> <!-- by one element. -->
> <xsl:copy-of
> select="$result" />
>
> <test1><xsl:value-of select="$count" /></test1>
>
> </xsl:with-param>
> </xsl:call-template>
> </xsl:when>
> <xsl:otherwise>
> <testtest>
> <xsl:copy-of select="$result" />
> </testtest>
> </xsl:otherwise>
> </xsl:choose>
> </xsl:template>
>
> <xsl:template match="/">
> <xsl:call-template name="test" />
> </xsl:template>
> </xsl:stylesheet>
>
> Using Saxon 8.4 gives the correct output:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <testtest>
>     <test1>10</test1>
>     <test1>9</test1>
>     <test1>8</test1>
>     <test1>7</test1>
>     <test1>6</test1>
>     <test1>5</test1>
>     <test1>4</test1>
>     <test1>3</test1>
>     <test1>2</test1>
>     <test1>1</test1>
> </testtest>
>
> Using Saxon 8.5 gives only this:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <testtest>
>     <test1>10</test1>
> </testtest>
>
> After putting copy-of AFTER the added element:
>
> <test1><xsl:value-of select="$count" /></test1>
> <xsl:copy-of select="$result" />
>
> the result is correct:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <testtest>
>     <test1>1</test1>
>     <test1>2</test1>
>     <test1>3</test1>
>     <test1>4</test1>
>     <test1>5</test1>
>     <test1>6</test1>
>     <test1>7</test1>
>     <test1>8</test1>
>     <test1>9</test1>
>     <test1>10</test1>
> </testtest>
>
> I would like to know if this is indeed a bug in Saxon 8.5 or
> am I doing  
> something wrong.
> I'd appreciate any help.
>
> Krzysztof Nowicki
>
>
> -------------------------------------------------------
> SF.Net email is Sponsored by the Better Software Conference & EXPO
> September 19-22, 2005 * San Francisco, CA * Development
> Lifecycle Practices
> Agile & Plan-Driven Development * Managing Projects & Teams *
> Testing & QA
> Security * Process Improvement & Measurement *
> http://www.sqe.com/bsce5sf
> _______________________________________________
> saxon-help mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/saxon-help
>




-------------------------------------------------------
SF.Net email is sponsored by:
Tame your development challenges with Apache's Geronimo App Server. Download
it for free - -and be entered to win a 42" plasma tv or your very own
Sony(tm)PSP.  Click here to play: http://sourceforge.net/geronimo.php
_______________________________________________
saxon-help mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/saxon-help
Reply | Threaded
Open this post in threaded view
|

Re: Problem with passing variables during a recursion

Dimitre Novatchev
> Also, as a result of discussion on
> this list last week with Dimitre Novatchev, this construct should benefit
> from further optimisations in the next release. (At present Saxon copies the
> list of references to the nodes, which is already much better than making a
> deep copy of the nodes. In future it won't even copy the list of references,
> it will simply reuse the same list.)


Thank you very much for this, Mike!!


Cheers,
Dimitre Novatchev


-------------------------------------------------------
SF.Net email is sponsored by:
Tame your development challenges with Apache's Geronimo App Server. Download
it for free - -and be entered to win a 42" plasma tv or your very own
Sony(tm)PSP.  Click here to play: http://sourceforge.net/geronimo.php
_______________________________________________
saxon-help mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/saxon-help