GNOME Bugzilla – Bug 62565
problem with global variable node-sets and apply-templates
Last modified: 2009-08-15 18:40:50 UTC
It appears that global variable node-sets are not being handled the same as main document node sets or node-sets brought in from an external document. I have included the xsl/xml combo to test it. xsl: problem.xsl ------------------ <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:common="http://exslt.org/common"> <xsl:output method="xml" indent="yes" /> <!-- Quick description...so what I notices was when I did apply-templates on a node-set variable that I had constructed in the page, it wasn't passing the param. Then, I realized the problem was really with how it was handling these variable node-sets. The example is thorough...check it out --> <xsl:variable name="inline_nodeset"> <node>first element</node> <node>second element</node> <node>third element</node> </xsl:variable> <xsl:variable name="document_nodeset" select="document('problem.xml')/root/node"/> <xsl:template match="/"> <xsl:element name="results"> <xsl:element name="out"> <xsl:attribute name="document">main_nodeset</xsl:attribute> <xsl:element name="description">Accessing the main document behaves as expected</xsl:element> <xsl:apply-templates select="root/node"> <xsl:with-param name="foo">bar</xsl:with-param> </xsl:apply-templates> <xsl:element name="reference_by_position_example"> <xsl:copy-of select="root/node[1]"/> </xsl:element> </xsl:element> <!-- notice for the nodeset created in the stylesheet, it is necessary to access it differently than the other two (1&3) nodesets in this stylesheet...taking off the reference to "node" in both of these causes serious problems --> <xsl:element name="out"> <xsl:attribute name="document">inline_nodeset</xsl:attribute> <xsl:element name="description">Accessing an inline nodeset behaves differently than both main document nodesets and nodesets pulled in from another file</xsl:element> <!-- this way does not work, it does not pass the param value --> <xsl:apply-templates select="common:node-set($inline_nodeset)"> <xsl:with-param name="foo">bar</xsl:with-param> </xsl:apply-templates> <!-- this way works, it passes the param value (both ways pass the selected node --> <xsl:apply-templates select="common:node-set($inline_nodeset)/node"> <xsl:with-param name="foo">bar</xsl:with-param> </xsl:apply-templates> --> <xsl:element name="reference_by_position_example"> <!-- this way works, take off the word "node" at the end and segfault --> <xsl:copy-of select="common:node-set($inline_nodeset)/node[1]"/> </xsl:element> </xsl:element> <xsl:element name="out"> <xsl:attribute name="document">document_nodeset</xsl:attribute> <xsl:element name="description">Accessing a nodeset pulled from a document behaves just as a nodeset from the main document</xsl:element> <xsl:apply-templates select="common:node-set($document_nodeset)"> <xsl:with-param name="foo">bar</xsl:with-param> </xsl:apply-templates> <xsl:element name="reference_by_position_example"> <xsl:copy-of select="common:node-set($document_nodeset)[1]"/> </xsl:element> </xsl:element> </xsl:element> <!-- Now, run the next line all by itself in this template and see that the output is just garbage. Technically, if you create a result tree fragment like above, this should just be a node-set of 3 nodes, so accessing the node at position one can be done as follows ... <xsl:copy-of select="common:node-set($inline_nodeset)[1]"/> --> </xsl:template> <xsl:template match="node"> <xsl:param name="foo"/> <xsl:element name="match"> <xsl:attribute name="param"><xsl:value-of select="$foo"/></xsl:attribute> <xsl:value-of select="current()"/> </xsl:element> </xsl:template> </xsl:stylesheet> xml: problem.xml ----------------- <?xml version="1.0" encoding="utf-8"?> <root> <node>first element</node> <node>second element</node> <node>third element</node> </root> Dan Allen
Hum, I have tried and checked the example. First the explanation from Tom Broyer is right, it is not a bug, the second use case is trying to make an invalid use of a Result Value Tree, not much can be done about this, it's the spec. His answer in the list seems right and detailed: http://mail.gnome.org/archives/xslt/2001-October/msg00106.html Concerning the following comment: <!-- this way works, take off the word "node" at the end and segfault --> <xsl:copy-of select="common:node-set($inline_nodeset)/node[1]"/> Well I have tried it: - removing just the word "node" generates an invalid XPath expression which is properly caught at stylesheet compilation: Error xpath.c:7555: Invalid expression common:node-set($inline_nodeset)/[1] ^compilation error: file pbm.xsl line 65 element copy-of xsl:copy-of : could not compile select expression 'common:node-set($inline_nodeset)/[1]' - removing the full end of the expression resulting in <xsl:copy-of select="common:node-set($inline_nodeset)"/> the output will then show the "fake" node: <reference_by_position_example> <fake> <node>first element</node> <node>second element</node> <node>third element</node> </fake> </reference_by_position_example> which doesn't seems bad, it allow to pinpoint the misuse of the Result Value tree. So really after multiple review it seems the libxslt behaviour in this case cannot be classified as a bug. But feel free to reopen it if you have more information that's it's not the case, thanks, Daniel
Okay seems it can be closed, Daniel