Subject: Re: [xsl] passing intermediate result while recursively building nodeset From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx> Date: Fri, 3 May 2002 16:10:51 +0100 |
Hi Paul, > I have question which is a variation of a previous question I had > ... I'd like to recursively build up a nodeset, and I'd like to pass > the intermediate result on with each recursive call. You could achieve what you're aiming for by creating a new result tree fragment and converting that to a node set to pass on to the next call. Something like: <xsl:template name="myTemplate"> <xsl:param name="nodes" select="/.." /> <xsl:if test="count($nodes) < 5"> <xsl:variable name="newNodes"> <xsl:copy-of select="$nodes" /> <a i="3" /> </xsl:variable> <xsl:call-template name="myTemplate"> <xsl:with-param name="nodes" select="exsl:node-set($newNodes)/*" /> </xsl:call-template> </xsl:if> </xsl:template> Obviously this one adds the same node each time and stops when it reaches 5 nodes, but you get the general idea. > Is this possible/reasonable/efficient? It's possible, if you're using 1.1, 2.0 or an extension node-set() function; otherwise it isn't, because when you create an element, then it's in a result tree fragment which you can't treat in the same way as a node. I'm not sure if it's reasonable -- it really depends on what your goal is, and you haven't described that. This method isn't particularly efficient, because it involves a lot of creation of new nodes. However your requirement for the new set of nodes to be *ordered* means that I don't think you can avoid this, at least in XSLT 1.0/1.1. (It might be that using the union operator gives you what you want in a particular implementation -- it depends on how the implementation orders nodes from different trees.) > I was looking at the union operator, but it appears that there is no > guarantee about the order of the elements in the resulting set and I > would like to keep them ordered. If 1.1 can't handle this, will it > be something that 2.0 will be able to do? XPath 2.0 does away with "node sets" and replaces them by "sequences", which of course do have an order. That makes this task a lot more efficient because you don't have to re-copy the nodes that are passed in each time. Instead, you can do: <xsl:template name="myTemplate"> <xsl:param name="nodes" select="/.." /> <xsl:if test="count($nodes) < 5"> <xsl:variable name="newNode"> <a i="3" /> </xsl:variable> <xsl:call-template name="myTemplate"> <xsl:with-param name="nodes" select="($nodes, $newNode/*)" /> </xsl:call-template> </xsl:if> </xsl:template> The expression ($nodes, $newNode/*) creates a sequence that contains all the nodes from $nodes followed by the element created within the $newNode variable. Cheers, Jeni --- Jeni Tennison http://www.jenitennison.com/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] passing intermediate resu, David Carlisle | Thread | RE: [xsl] passing intermediate resu, Michael Kay |
[xsl] Re: passing intermediate resu, Dimitre Novatchev | Date | [xsl] insert tags out of context in, Peter Carlson |
Month |