RE: [xsl] What to use instead of a mutable variable ?

Subject: RE: [xsl] What to use instead of a mutable variable ?
From: "Michael Kay" <mhk@xxxxxxxxx>
Date: Wed, 18 Aug 2004 13:30:14 +0100
I haven't read this in enough detail to understand the requirement fully,
but you may find that the XSLT 2.0 facility of tunnel parameters provides a
way forward.

Michael Kay 

> -----Original Message-----
> From: IceT [mailto:icetbr@xxxxxxxxxxxx] 
> Sent: 17 August 2003 23:01
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: Re: [xsl] What to use instead of a mutable variable ?
> 
> But then every template would need to have the parameter, and I have 
> hundreds of them, and only two actually need it!
> 
> Josh Canfield wrote:
> 
> >It's not very clear to me what you are trying to do but I'm going to
> >guess that you are processing two documents, one with layout
> >information, and the other with the actual data. You want to tell a
> >template that is processing your layout nodes what book it 
> is supposed
> >to be getting data from?
> >
> >Instead of using a global variable to store the position, try passing
> >the position to the templates using <xsl:with-param> inside of the
> ><xsl:apply-templates> and <xsl:call-template> elements. You 
> could also
> >just pass the book node as the parameter...
> >
> >Below is an implementation similar to what I think you are 
> trying to do...
> >
> >**XSL**
> >
> ><?xml version="1.0"?>
> ><xsl:stylesheet
> >  version="1.0"
> >  xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
> ><xsl:output method="xml" indent="yes"/>
> >
> >  <xsl:variable name="layout" 
> select="document('layout.xml')/layout"/>
> >  <xsl:variable name="books" select="/books"/>
> >
> >  <xsl:template match="/books">
> >    <xsl:for-each select="book">
> >      <xsl:apply-templates select="$layout/*">
> >        <xsl:with-param name="position" select="position()"/>
> >      </xsl:apply-templates>
> >    </xsl:for-each>
> >
> >  </xsl:template>
> >
> >  <xsl:template match="insertItem">
> >    <xsl:param name="position"/>
> >    <outer-item-stuff>
> >    <xsl:apply-templates>
> >      <xsl:with-param name="position" select="$position"/>
> >    </xsl:apply-templates>
> >    </outer-item-stuff>
> >  </xsl:template>
> >
> >  <xsl:template match="insertName">
> >    <xsl:param name="position"/>
> >    <xsl:value-of select="$books/book[position()=$position]/name"/>
> >  </xsl:template>
> >
> >  <!-- copy everything, continue param propagation -->
> >  <xsl:template match="@*|*">
> >    <xsl:param name="position"/>
> >    <xsl:copy>
> >      <xsl:apply-templates>
> >        <xsl:with-param name="position" select="$position"/>
> >      </xsl:apply-templates>
> >    </xsl:copy>
> >  </xsl:template>
> >
> ></xsl:stylesheet>
> >** Book.xml **
> >
> ><?xml version="1.0"?>
> >
> ><books>
> >  <book>
> >    <name>The Lion, the Witch and the Wardrobe</name>
> >  </book>
> >  <book>
> >    <name>Prince Caspian</name>
> >  </book>
> >  <book>
> >    <name>The Voyage of the 'Dawn Treader'</name>
> >  </book>
> >  <book>
> >    <name>The Silver Chair</name>
> >  </book>
> ></books>
> >
> >** layout.xml **
> >
> ><?xml version="1.0"?>
> >
> ><layout>
> >
> ><insertItem>
> >  <name>
> >    <insertName/>
> >  </name>
> >  <hr/>
> ></insertItem>
> >
> ></layout>
> >
> >** Output **
> ><?xml version="1.0" encoding="utf-8"?>
> ><outer-item-stuff>
> >
> >   <name>
> >    The Lion, the Witch and the Wardrobe
> >  </name>
> >
> >   <hr/>
> >
> ></outer-item-stuff>
> ><outer-item-stuff>
> >
> >   <name>
> >    Prince Caspian
> >  </name>
> >
> >   <hr/>
> >
> ></outer-item-stuff>
> ><outer-item-stuff>
> >
> >   <name>
> >    The Voyage of the 'Dawn Treader'
> >  </name>
> >
> >   <hr/>
> >
> ></outer-item-stuff>
> ><outer-item-stuff>
> >
> >   <name>
> >    The Silver Chair
> >  </name>
> >
> >   <hr/>
> >
> ></outer-item-stuff>--------------------------------
> >
> >Hope that helps,
> >Josh
> >
> >On Sun, 17 Aug 2003 00:52:09 -0300, IceT <icetbr@xxxxxxxxxxxx> wrote:
> >  
> >
> >>Hello everebody,
> >>
> >>I have something like this code in my xsl
> >>
> >><xsl:template match="insertItem">
> >>   <xsl:for-each select="$book/itens">
> >>       <xsl:apply-templates select="$layout//insertItens/*" />
> >>   </xsl:for-each>
> >></xsl:template>
> >>
> >><xsl:template match="insertName">
> >>   <xsl:value-of select="$book/itens/name"/>
> >></xsl:template>
> >>
> >><xsl:template match="@*|*">
> >>   <xsl:copy>
> >>       <xsl:apply-templates select="@*|node()" />
> >>   </xsl:copy>
> >></xsl:template>
> >>
> >>How can I make the template "insertItens" to use a diferrent name
> >>everytime it is called? I want to achieve something like
> >>
> >><xsl:template match="insertName">
> >>    <xsl:param name="position" />
> >>   <xsl:value-of select="$book/itens/name[$position]"/>
> >></xsl:template>
> >>
> >>though I ca't call this template directly, because there is 
> some nodes
> >>tha need to be "copied" to the output first when the "for 
> each" is being
> >>processed. I needed an alterable global variable, but that is not
> >>possible in XSL.
> >>
> >>Did I explain the situation correctly?
> >>
> >>Thanks.

Current Thread