Search

Is anyone able to help me here:

I am using the String Utility functions to split a list of numbers stored in coma separated node. so that I end up with the following:

<cat><entry>10</entry><entry>11</entry><entry>6</entry></cat>

This bit is being applied in a template and output to my result master.xsl page.

What I then need to do with this nodeset is match each entry node value against a list of category entries...

What would be the best way to transform this node set for use in another match so that the above is able to be used in a statement such as this:

<xsl:value-of select="//data/prefs/categories/entry[@id ='cat/entry/.']/catname"/>

My datasource is an external xml file with fixed values so I need it to work this way really.

Was looking at an umbraco forum post that referenced a similar request but my for-each looping just spits out en error in xpathr :(

And based on the umbraco method I was looking at, I thought something like this would work:

<xsl:template match="categories" >
<xsl:variable name="category" select="cat[@lang = $lang]/."/>
<xsl:variable name="catlist"     select="string:split($category,',','cat','entry')" />
<xsl:for-each select="$catlist/cat/entry">
  <p><xsl:value-of select="//data/preferences/categories/entry[@id = '.']/cat"/></p>
</xsl:for-each>    

I think you want exslt:node-set to achieve a $catlist XML fragment that can be processed.

Thanks Mark,

I seem to have the right count being output, but not seeing any values spat out in my LI's:

<xsl:template match="categories">
<xsl:variable name="category" select="cat[@lang = $lang]/."/>
<xsl:variable name="catlist" select="string:split($category,',')"/>
<xsl:for-each select="exsl:node-set($catlist)/nodeset/node">
  <li><xsl:copy-of select="//data/preferences/categories/entry[@id = 'node']/cat[@lang=$lang]"/></li>
</xsl:for-each>

My result looks like this:

<div>
      <h1>Project title</h1>
      <h2>ID: 1</h2>
      <iframe src="http://player.vimeo.com/video/47100629?title=0&amp;byline=0&amp;color=c8dd63" width="512" height="288"/>
      <p>some HTML encoded with escaped entities</p>
      <ul id="proj-cat">
        <li/>
        <li/>
      </ul>
    </div>

Where I know this project had 2 coma separated ID's but the LI's don't seem to include the entry values I'm after. See this Xpathr code of gist for what I'm playing with.

EDIT: I guess what is being discussed here is what I'm almost trying to achieve. Is it that my variables should be moved outside of the match? bugs me how I can't quite figure out what's going on :(

Try this

<li><xsl:copy-of select="//data/preferences/categories/entry[@id = 'node']/cat[@lang=$lang]/text()"/></li>

Edit: Actually, don't.

I think it has something to do with the node-set function creating it's own tree in a temp doc and the lack of access to the original XML data from this tree.. the root node of the node-set is the only root node I have access to inside the for-each.. gonna try a variable outside the loop for getting the categories... hrmmph

gonna try a variable outside the loop for getting the categories

Yup, or inside the loop. I find it necessary when comparing elements in different contexts.

Ok so I've managed to re-jigg the code but could someone point out why I only get one category result returned in this code: #lost :(

<xsl:template match="categories" >
<xsl:variable name="category" select="cat[@lang = $lang]/."/>
<xsl:variable name="catlist" select="string:split($category,',')"/>

  <xsl:for-each select="//data/preferences/categories/entry">
    <xsl:if test="contains(@id,exsl:node-set($catlist)/nodeset/node)">
      <li><xsl:value-of select="cat[@lang=$lang]/."/></li>
    </xsl:if>
  </xsl:for-each>

Thanks Funk for that.

Finally figured it out:

<xsl:template match="categories" mode="in">
<xsl:variable name="category" select="cat[@lang = $lang]/."/>
<xsl:variable name="catlist" select="string:split($category,',')"/>
<xsl:variable name="catID" select="exsl:node-set($catlist)/nodeset/node"/>

<xsl:for-each select="//data/preferences/categories/entry">

    <xsl:if test="@id = $catID">
      <li><xsl:value-of select="cat[@lang=$lang]/."/></li>
    </xsl:if>
  </xsl:for-each>             

Right, wine o'clock.

Can admin add solved to title of post and poss change word 'sting' to 'string' please :)

I haven't read the entire thread, but I'd like to answer the question about using exsl:node-set() and not being able to refer back to the original XML source.

The solution involves using document().

Say that you have <xsl:for-each select="exsl:node-set(subset)/node">, your context here would be referencing a different temporary result tree. Naturally, any further XPath within the for-each instruction will be relative to the temp tree. If you want to refer to the source document, you can simply use document()/node.

Typically, the cleaner approach is to store the temp tree in a variable and the source tree as another variable. That way the XPath becomes a lot clearer to understand:

i.e. $temp/node v.s. $source/node.

Hi Allen, thanks for the tip. I am indeed storing the temp tree and source tree in variables in a template match but outside if the for-each. I'll have a play with my gist to see how document fits in. Cheers

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details