Thursday, July 12, 2007

Dealing with tokenize, atomic values and a for-each

I've been working on a little identity transform issue, where I needed to resolve some transclusions in an XML document. Some of the ref attributes in the doc also contained multiple space-separated values that needed to be processed separately.

After a few Googles and a great deal of hacking, I was able to process refs with a single attribute value. I Googled a bit more and found some help (including a great article from Bob DuCharme) to process the multiple values using the tokenize function in XSLT 2.0.

I kept running into an odd error though: "Cannot select a node here: the context item is an atomic value". I thought it was some kind of XPath issue, so tried a number of different hacks to get around the issue to no avail. Finally, I Googled on the error message and found the solution. Here's the code snippet that I used:

  <xsl:template match="widgetRef">
    <xsl:variable name="root" select="/"/>
    <xsl:variable name="widgetID" select="tokenize(@stuff, ' ')"/>
    <xsl:for-each select="$widgetID">
       <xsl:variable name="widgetNum" select="."/>
      <xsl:copy-of select="$root//widget[@id=$widgetNum]"/>
    </xsl:for-each>
  </xsl:template>

Hope this helps someone. It took me a while to discover that I needed to reset the context when using tokenize within a for-each.

3 comments:

Anonymous said...

I just want to say THANK YOU VERY VERY MUCH to the author, who is post this code.
It helps me a lot.
Thanks again

Anonymous said...

Thank you very much for your help!

Anonymous said...

Thanks as well. It should be pointed out in instructional materials that this is a more common problem than it would seem.