GNOME Bugzilla – Bug 321112
$variable out of scope in xsl:number count="pattern[$variable]"
Last modified: 2021-06-25 17:44:11 UTC
Please describe the problem: Basically, any occurrence of a reference to an xsl:variable, via the "$variable" notation is out of scope within the count="pattern" predicate. This leads to undefined variable errors and or patterns which cannot be compiled. Some sample xslt code: <?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'> <xsl:strip-space elements="article chapter section "/> <xsl:output method="text"/> <xsl:template match="biblioref"> <xsl:variable name="cite.target" select="@endterm" /> <xsl:variable name="tagA" select="concat($cite.target, '-A')"/> <xsl:variable name="tagX" select="concat($cite.target, '-X')"/> <xsl:variable name="tagW" select="concat($cite.target, '-W')"/> <xsl:text>target: </xsl:text> <xsl:value-of select="$cite.target"/> <xsl:variable name="cite.preceding"> <!-- Try insert one of these count attributes in the following xsl:number element None of these work because all $variables seem to be out of scope count="biblioref[@endterm = concat($cite.target, '-A') or @endterm = concat($cite.target, '-X') or @endterm = concat($cite.target, '-W')]" /> count="biblioref[@endterm = $tagA or @endterm = $tagX or @endterm = $tagW ]" level="any"/> count="biblioref[@endterm = $tagA] | biblioref[@endterm = $tagX] | biblioref[@endterm = $tagW ]" /> count="biblioref[@endterm = $tagX]" /> Without $variables these ones work perfectly. count="biblioref[@endterm ='Bob01-X']" /> count="biblioref[@endterm ='Bob01-X' or @endterm ='Bob01-A' or @endterm ='Bob01-W' ]" /> --> <xsl:number from="bibliography" level="any" count="biblioref[@endterm = concat($cite.target, '-A') or @endterm = concat($cite.target, '-X') or @endterm = concat($cite.target, '-W')]" /> </xsl:variable> <xsl:text> count : </xsl:text> <xsl:value-of select="$cite.preceding"/> </xsl:template> </xsl:stylesheet> Steps to reproduce: xsltproc test.xsl test.xml where test.xml is something like this: <?xml version="1.0"?> <!DOCTYPE article [ ] > <article> <title>xsl:number count="pattern[$variable]" test</title> <chapter> <section> <para> Basically we need some data to serve as a test for inserting an xsl:variable reference into a predicate condition applied to a pattern used as the attribute value for the "count" attribute of the xsl:number XSLT element. <citation><biblioref endterm="Bob01-A"/></citation> <citation><biblioref endterm="Bob01-X"/></citation> <citation><biblioref endterm="Bob01-W"/></citation> </para> </section> <section> <para> <citation><biblioref endterm="Norm02-W"/></citation> <citation><biblioref endterm="Bob01-A"/></citation> <citation><biblioref endterm="Bob01-W"/></citation> </para> </section> <section> <para> <citation><biblioref endterm="Norm02-X"/></citation> <citation><biblioref endterm="Bob01-X"/></citation> <citation><biblioref endterm="Bob01-X"/></citation> <citation><biblioref endterm="Norm02-X"/></citation> <citation><biblioref endterm="Norm02-X"/></citation> <citation><biblioref endterm="Bob01-X"/></citation> <citation><biblioref endterm="Bob01-X"/></citation> </para> </section> <bibliography><title>Bibliography</title></bibliography> </chapter> <chapter> <section> <para> This is just to test the "from" attribute to see that xsl:number-ing really does restart after the previous bibliography element. <citation><biblioref endterm="Norm02-W"/></citation> <citation><biblioref endterm="Mike05-W"/></citation> <citation><biblioref endterm="Mike05-A"/></citation> </para> </section> <section> <para> <citation><biblioref endterm="Bob01-A"/></citation> <citation><biblioref endterm="Bob01-X"/></citation> <citation><biblioref endterm="Bob01-W"/></citation> </para> </section> <section> <para> <citation><biblioref endterm="Norm02-X"/></citation> <citation><biblioref endterm="Norm02-A"/></citation> <citation><biblioref endterm="Norm02-A"/></citation> <citation><biblioref endterm="Norm02-A"/></citation> <citation><biblioref endterm="Mike05-W"/></citation> </para> </section> <bibliography><title>Bibliography</title></bibliography> </chapter> </article> Actual results: $> xsltproc test.xsl test.xml XPath error : Undefined variable Expected results: Does this happen every time? yes Other information:
Not a bug: http://www.w3.org/TR/xslt#number "The count attribute is a pattern that specifies what nodes should be counted at those levels." Definition for pattern is there: http://www.w3.org/TR/xslt#patterns As you can see in production rules [1] to [6] you can't embed a variable reference in a pattern. This is not a bug. Daniel
Thanks Daniel, I've greatly appreciated using xsltproc, its a marvellous program. It seems to me though that in this case there may be an oversight because Reading from http://www.w3.org/TR/xslt#patterns: According to rule [1] a Pattern can contain a LocationPathPattern According to rule [2] a LocationPathPattern can contain a RelativePathPattern According to rule [4] a RelativePathPattern can contain a StepPattern According to rule [5] a StepPattern can contain a Predicate Now in http://www.w3.org/TR/xpath#NT-Predicate According to rule [8] a Predicate contains a PredicateExpr According to rule [9] a PredicateExpr is an Expr and in http://www.w3.org/TR/xpath#NT-Expr According to rule [14] an Expr is an OrExpr According to rule [21] an OrExpr is comprised of individual AndExpr According to rule [22] an AndExpr contains EqualityExpr According to rule [23] an EqualityExpr contains RelationalExpr According to rule [24] a RelationalEXpr contains AdditiveExpr According to rule [25] an AdditiveExpr contains MultiplicativeExpr According to rule [26] a MultiplicativeExpr contains a UnaryExpr According to rule [27] a UnaryExpr contains a UnionExpr now: According to rule [18] a UnionExpr contains a PathExpr According to rule [19] a PathExpr contains a FilterExpr According to rule [20] a FilterExpr contains a PrimaryExpr Finally: According to rule [15] a PrimaryExpr contains a VariableReference Q.E.D. (quite erroneously done) Regretfully, I believe this is correct and VariableReferences should be permitted in predicates and this is a bug. Thanks again Doug
oops. forgot to reopen.
As one would expect, this bug also affects the 'match' attribute on 'xsl:template' elements, as 'match' attributes also contain XSLT patterns. I agree with Doug that this is a bug, as the Pattern production rules refer to the Predicate production over in the XPath rec, and predicates can contain variable references. The "Patterns" section of the XSLT rec even makes this explicit: "Predicates in a pattern can use arbitrary expressions just like predicates in a location path." It would be easy to provide an additional test case, upon request.
Okay only pattern in template are forbidden from using variables, I confused the two... http://www.w3.org/TR/xslt#section-Defining-Template-Rules "It is an error for the value of the match attribute to contain a VariableReference." so for #2, yes you are right, I need to looks at this, but for #4 no you are wrong it's forbidden, go reread the spec. Daniel
This should be fixed now, see https://gitlab.gnome.org/GNOME/libxslt/-/issues/6