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 > 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 |
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 > 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 |
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 > 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 |
> 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 |
Free forum by Nabble | Edit this page |