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

Subject: Re: [xsl] What to use instead of a mutable variable ?
From: Josh Canfield <joshcanfield@xxxxxxxxx>
Date: Tue, 17 Aug 2004 15:21:43 -0700
Well... maybe someone else will tell you differently but you are going
to have to pass enough information to the matched template so that it
can pull the correct data from the other document, and passing down
parameters is the way to do it.

Out of hunderds of templates you only pull information from the $book
variable in two of them? You only need to pass the parameters to
templates that either need the data, or could invoke a template that
needs the data.

Perhaps you could provide a better description of the actual problem
that you are trying to solve, maybe then someone can come up with a
better pattern to solve it.

Josh

On Sun, 17 Aug 2003 19:00:54 -0300, IceT <icetbr@xxxxxxxxxxxx> wrote:
> 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