Re: [xsl] Does <xsl:copy> use a lot of memory? Is there an alternative that is more efficient?

Subject: Re: [xsl] Does <xsl:copy> use a lot of memory? Is there an alternative that is more efficient?
From: Graydon <graydon@xxxxxxxxx>
Date: Mon, 3 Sep 2012 11:24:01 -0400
On Mon, Sep 03, 2012 at 03:12:40PM +0000, Costello, Roger L. scripsit:
> >> In other words, if I don't immediately output the results of
> >> xsl:copy, then memory consumption grows and grows. Yes?
> >
> >Potentially yes.
> 
> Okay, then I am in a pickle and I see no way out.
> 
> Recall the problem that I am tackling: I have an element with an idref
> attribute. I want to fetch the referenced element and inline it.
> Here's the template to do that:
> 
>     <xsl:key name="ids" match="*[@id]" use="@id"/>
> 
>     <xsl:template match="*[@idref]">
>         
>         <xsl:variable name="refed-element" select="key('ids',
>         @idref)"/>
>         
>         <xsl:copy>  <xsl:copy-of select="@* except @idref" />
>         <xsl:sequence select="$refed-element" /> </xsl:copy>
>         
>     </xsl:template>

But why are you creating a variable at all?

> However, the element that I just inlined may have a reference. So I
> store the results into a variable and then repeat the process on the
> content of the variable. But that may also result in inlining an
> element with a reference, so I store the results into another variable
> and process it. I keep repeating this process until there are no more
> references. (The references may be recursive so it is a bit more
> involved than this, but you get the idea.)

Replace the variable reference in the sequence select with the contents
of the select in the variable, and it should just work, no?  Presuming
you're getting the element you just inlined from the same source
document, anyway.

The processor should handle document order for you, and the template
will match everything with an @idref.  You don't need to force that with
some sort of explicit recursion.

> In the process I described above, I am creating a bunch of variables.
> But with each new variable that I create, the previous variables are
> no longer used. It seems like the previous variables should be garbage
> collected. Is there a way to signal to an XSLT processor, "Hey, I am
> done with this variable, please garbage collect it"?

Generally speaking, don't create variables unless you can't avoid it; I
think you can't avoid it if you need to multiply reference something in
many templates, if you have to pipeline the processing, or if you're
forced to do a switch between serialized and node-based processing.

So far as I can tell from your example, you don't need variables at all.

If you _are_ getting the inlined content from another document than your
primary source document, figure out how deep it can go, and run the one
pass version -- NOT the forced recursion version -- that many times.
C(n) is better than n^2 unless C is larger than n.  (this is where you
do the chained pipeline thing with variables.)

-- Graydon

Current Thread