xsl-list
[Top] [All Lists]

Re: [xsl] XSLT key() function document argument

2009-11-02 20:28:06
At 2009-11-02 17:16 -0800, Bill French wrote:
I have a stylesheet that initializes some keys based on content in the input document. Then, the stylesheet applies templates to a node set variable whose contents come from an external file. For awhile I was very confused, because the keys weren't accessible from the templates that were being applied in the different context.

<xsl:key name="c" match="rm:content" use="string(@name)"/>
<xsl:key name="l" match="rm:label" use="string(@name)"/>
<xsl:variable name="orig-context" select="/"/>

...

<xsl:variable name="wf">
    <xsl:copy-of select="document($wf-filepath)"></xsl:copy-of>
</xsl:variable>

I find it interesting you are using <xsl:copy-of/> ... why not just point to the document root node rather than occupying the memory by creating an entire copy of the document:

  <xsl:variable name="wf" select="document($wf-filepath)"/>

<xsl:template match="/rm:contentList">
    <xsl:apply-templates select="$wf"/>
</xsl:template>

<xsl:template match="rm:insert[(_at_)label]">
    <xsl:apply-templates select="key('l', @label, $orig-context)"/>
</xsl:template>

The variable $wf contains the rm:insert elements that are matched by the final template.

Now the question is -- is there a way to reference the "original" context, i.e., the document that processor originally encounters as the input tree? I've stored the document in the variable $orig-context, but this doesn't seem like an efficient or particularly elegant solution.

That is exactly how I would do it, with a global:

  <xsl:variable name="orig-context" select="/"/>

... and there is nothing inefficient at all about this since it is only storing a single node ... just like in my suggested modification for $wf above.

Is there some special syntax to access the original context from a context created when applying templates to a node set variable?

Nothing special about applying templates to a node set variable ... keeping the original context in a variable is entirely acceptable and quite common.

And, with my modification for $wf above you don't have a node set variable, you are just pushing another document through the template rules without incurring the overhead of creating the complete copy in a node set variable.

Remember that document() returns a document node (formerly called a root node) after reading the XML document into memory ... so the document is in memory somewhere, it just isn't *also* in a variable through your use of <xsl:copy/>.

I've often used a global variable storing the root node for precisely the purpose you've described. Not at all inefficient, nor wasteful, nor inelegant in my opinion.

I hope this helps.

. . . . . . . . . Ken

--
Upcoming:  hands-on XSLT, XQuery and XSL-FO Washington DC Nov 2009
Interested in other classes?  http://www.CraneSoftwrights.com/s/i/
Crane Softwrights Ltd.          http://www.CraneSoftwrights.com/s/
Training tools: Comprehensive interactive XSLT/XPath 1.0/2.0 video
Video lesson:    http://www.youtube.com/watch?v=PrNjJCh7Ppg&fmt=18
Video overview:  http://www.youtube.com/watch?v=VTiodiij6gE&fmt=18
G. Ken Holman                 mailto:gkholman(_at_)CraneSoftwrights(_dot_)com
Male Cancer Awareness Nov'07  http://www.CraneSoftwrights.com/s/bc
Legal business disclaimers:  http://www.CraneSoftwrights.com/legal


--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--

<Prev in Thread] Current Thread [Next in Thread>