Re: [xsl] using str:tokenize named template results

Subject: Re: [xsl] using str:tokenize named template results
From: "vwiswell" <vwiswell@xxxxxxxxxxx>
Date: Fri, 28 Mar 2008 17:11:20 -0500
David and Michael, thank you both for your responses. I added a global variable 'root', as suggested and ended up with this:

<xsl:template name="buildTable">
  <xsl:param name="tokens"/>
  <xsl:variable name="ns" select="msxsl:node-set($tokens)"/>
  <xsl:for-each select="$ns/token">
    <p>token: <xsl:value-of select="." /></p>
      <xsl:for-each select="$root//city[. = $ns/token]">
      <xsl:sort select="city"/>
     <p>city: <xsl:value-of select="." /></p>
     </xsl:for-each>
 </xsl:for-each>
</xsl:template>

The tokens in this case are: A City, B City, C City

My output looks like this:

token: A City
city: A City
city: A City
city: A City
token: B City
city: A City
city: A City
city: A City
token: C City
city: A City
city: A City
city: A City

It looks like the token value here

<xsl:for-each select="$root//city[. = $ns/token]">

never gets beyond the first value, although it is looping through the correct number of times (3). Do I need to qualify $ns/token somehow?

Thanks for the tip about text(). I will keep its use to a minimum :)


On Fri, 28 Mar 2008 21:28:56 -0000 "Michael Kay" <mike@xxxxxxxxxxxx> wrote:
You're forgetting that a path expression starting with "/" or "//" selects
within the document that contains the context node - which in this case is
the document constructed by the str:tokenize template. You need to create a
global variable say <xsl:variable name="root" select="/"/> and then select
relative to that: select="$root//city[text() = $ns/token/text()]".


Or better,

$root//city[. = $ns/token]"

You don't want to access the text nodes explicitly because comments or
processing instructions would stop your code working.


Michael Kay
http://www.saxonica.com/


-----Original Message-----
From: vwiswell [mailto:vwiswell@xxxxxxxxxxx] Sent: 28 March 2008 19:59
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: [xsl] using str:tokenize named template results


The str:tokenize template works beautifully (I am required to use xslt 1.0). I am using it to split the input from a multiple select box submitted from an html page thusly:

       <xsl:variable name="inValues">
         <xsl:call-template name="str:tokenize">
            <xsl:with-param name="string" select="$input" />
         </xsl:call-template>
      </xsl:variable>

I want to loop through the tokens checking for matches in my main input, an xml file. So I need nested for-each loops, the outer one looping through my tokens from str:tokenize and the inner one looping through <city>s in my doc.

The xml looks like this:

<sites>
   <site>
     <city>A City</city>
     <institution>Axxxxx Univ.</institution>
     <administers>to any student</administers>
     <schedule>2 times per month</schedule>
     <additional_costs>$15 admin. fee</additional_costs>
     <contact_information>(123) 123-1234</contact_information>
   </site>
   <site>
     <city>B City</city>
     <institution>Bxxxx College</institution>
     <administers/>
     <schedule/>
     <additional_costs/>
     <contact_information/>
   </site>
   <site>
     <city>C City</city>
     <institution>Cxxxxx College</institution>
     <administers>to any student</administers>
     <schedule>1 time per month</schedule>
     <additional_costs>$10 refundable deposit</additional_costs>
     <contact_information>(123) 123-1234</contact_information>
   </site>
   ...
</sites>

I'm not getting any output, so I think I have context issues, but I'm not sure how to fix it. I don't really understand the relationship between the str:tokenize results and my xml doc. It seems analogous to multiple input xml docs, but I'm not sure how to code it. This is what I have tried:

<xsl:template name="buildTable">
<xsl:param name="tokens"/>
<xsl:variable name="ns" select="msxsl:node-set($tokens)"/>
<xsl:for-each select="$ns/token">
<xsl:value-of select="text()" /><br /><!-- this works and proves the tokens are as expected -->
<xsl:for-each select="//city[text() = $ns/token/text()]">
<xsl:sort select="city"/>
<xsl:value-of select="text()" /><br /><!-- this produces no output -->
</xsl:for-each>
</xsl:for-each>
</xsl:template>


If I remove the token (outer) for-each, I get output, but only for the first token (obviously). The tokens get passed to this template just fine.

I'd really appreciate a nudge in the right direction. Thanks.

Current Thread