Using XSLT I print these persons using a for-each loop. I want the name of the person to be printed every time, but I want to use the title as a header to group the persons I'm listing. The result I want on the screen is:
Art Director Jakob Lea
Project Manager Jonas
Web Developer Thomas Johan
How would I accomplish this using XSLT? Is there a way to track if the present value in the loop is different from the previous value and if it is, print it to screen. I suspect the solution involves using calling another template, but I'm having a hard time finding the best solution.
Chriztian, I think your example could work! The nodes are not sorted in any specific order in Umbraco, but in the XSLT I sort them by title and that should be enough.
Hmm, I guess I jumped the gun there. This solution works if the nodes are ordered in the correct order in the umbraco backend. In my case they are not - I use a sort select in my XSLT to sort the nodes in the correct order.
So it seems that preceding-sibling::node[1] ignores any sorting directives in the XSLT and uses the order the nodes have in Umbraco.
"The axis works on the XML source's internal tree-representation (the XSLT processor builds the tree before applying a stylesheet). Therefore,
when you say "xsl:sort", it just begins to process the nodes in the order you specify, sorting can't affect any axis processing."
Answering my own question: it seems like the result from the first for-each loop is not really a nodeset, but something called a tree fragment. In order to make it a nodeset you need to use exslt:node-set, like this:
Oh yes - that's why I said "If your data is already sorted by title", because this was the easy solution :-)
I'm a little uncertain if you've solved your problem using the node-set() function? (Incidentally, the function is already available in Umbraco as either msxml:node-set() or Exslt.ExsltCommon:node-set())
If you're still looking for a solution you should check out (i.e. google for) 'grouping' and 'muenchian' for the gory details... (or ask for an example)
Print to screen only when a value is different from the preceding value?
Hi!
Let's say I have an XML-structure that looks like this:
Using XSLT I print these persons using a for-each loop. I want the name of the person to be printed every time, but I want to use the title as a header to group the persons I'm listing. The result I want on the screen is:
Art Director
Jakob
Lea
Project Manager
Jonas
Web Developer
Thomas
Johan
How would I accomplish this using XSLT? Is there a way to track if the present value in the loop is different from the previous value and if it is, print it to screen. I suspect the solution involves using calling another template, but I'm having a hard time finding the best solution.
Thanks in advance!
/Thomas Kahn
Can't you adapt the data structure?
you could run a nested for each... where you list the <title> when the position is equal to 1
then insided that for each list the <name> where title = currentTitle --
hope that makes sense.
Hi Thomas,
If your data is already sorted by title (which your short fragment suggests) then the following template will be sufficient:
If that's not the case, you'll have to dive into "grouping" which can be quite a hassle in XSLT 1.0... let us know, if so.
/Chriztian
Chriztian, I think your example could work! The nodes are not sorted in any specific order in Umbraco, but in the XSLT I sort them by title and that should be enough.
Will try it first thing on Monday!
/Thomas
Chriztian - you just saved me a lot of headaches!
It worked like a charm - thanks!
/Thomas K
Hmm, I guess I jumped the gun there.
This solution works if the nodes are ordered in the correct order in the umbraco backend. In my case they are not - I use a sort select in my XSLT to sort the nodes in the correct order.
So it seems that preceding-sibling::node[1] ignores any sorting directives in the XSLT and uses the order the nodes have in Umbraco.
Bummer. Is there a way to get around this?
/Thomas Kahn
This was new to me:
"The axis works on the XML source's internal tree-representation (the XSLT processor builds the tree before applying a stylesheet). Therefore,
when you say "xsl:sort", it just begins to process the nodes in the order you specify, sorting can't affect any axis processing."
http://p2p.wrox.com/xslt/3040-sorting-preceding-sibling.html
This page contains a suggestion how to solve the problem by copying the sorted nodes to a new node set. In my code it looks like this:
I can print values from this new nodeset using:
...but as soon as I try something like this:
...I get Error parsing XSLT file.
Has anyone done this before in umbraco? If so, any clues how I can accomplish this?
Thanks in advance!
/Thomas K
Answering my own question: it seems like the result from the first for-each loop is not really a nodeset, but something called a tree fragment. In order to make it a nodeset you need to use exslt:node-set, like this:
You will also need to add the namespace to the stylesheet. I added xmlns:exslt="http://exslt.org/common" in my stylesheet.
After having done this, it works like expected (so far)!
This is totally new to me so I'd love any input or improvements on this.
/Thomas K
Hi Thomas,
Oh yes - that's why I said "If your data is already sorted by title", because this was the easy solution :-)
I'm a little uncertain if you've solved your problem using the node-set() function? (Incidentally, the function is already available in Umbraco as either msxml:node-set() or Exslt.ExsltCommon:node-set())
If you're still looking for a solution you should check out (i.e. google for) 'grouping' and 'muenchian' for the gory details... (or ask for an example)
/Chriztian
is working on a reply...