Split String Functions and matching ID's [solved]
This is an open discussion with 9 replies, filed under XSLT.
Search
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&byline=0&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.
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:
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:
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: