Altova Mailing List Archives>Archive Index >comp.text.xml Archive Home >Recent entries >Thread Prev - Re: Tip: Finding & counting unique nodes in XSL [Thread Next] Re: Tip: Finding & counting unique nodes in XSLTo: NULL Date: 6/1/2004 4:34:00 PM Victor <engmark-usenet@o...> wrote in news:c9h8ug$dcf$1@s...: > Piet Blok wrote: > >> However, I just cannot get rid of an ugly xsl:if. In my solution I >> select all elements and then I decide if the current element is a >> "new" element. See below: >> >> >> <xsl:template match="/"> >> <!-- select all Name elements --> >> <xsl:for-each select="//Name"> >> <!-- test if this Name element is new, based on the first character >> --> >> <xsl:if test="not(substring(current(),1,1) = >> substring >> (preceding::Name[substring(.,1,1)=substring(current(),1,1)],1,1))"> >> <!-- Display the first character --> >> <xsl:value-of select="substring(.,1,1)"/> >> <!-- Count occurences of element with the same starting character --> >> <xsl:value-of >> select="count(//Name[substring(.,1,1) >> =substring(current(),1,1)])"/> >> </xsl:if> >> </xsl:for-each> >> </xsl:template> >> >> Can you think of any way to move the if structure into the select >> clause? >> >> In a way the problem seems to be that there are three contexts to >> deal with: the context node (in this case the root node), the node >> that is currently under investigation for selection and the node that >> is compared to (between the square brackets). > > First, if you can split the Name into several strings, that would be a > good start. If you have control over the structure of the XML file, > keep each piece of information separate. Otherwise you'll get into the > same mess I was in when trying to make sense of MS Project XML files > (gross!). > > Then there is a funny thing about the test (changed the substring > function to a() to make it obvious): > a(current) = a(preceding::Name[a(.)=a(current)]) > So first you find a preceding Name which equals the current one, and > then compare it to the current one? This sounds like double work. > a(current) = a(preceding::Name) should be enough. > > By changing according to the previous paragraphs, you would have > something like a Name element and a New element, and you can do the > for-each as follows (providing that the New element occurs after the > Name): <xsl:for-each select="//Name[not(./following-sibling::New = > preceding::Name/following-sibling::New)]"> > > I haven't tested this, but perhaps someone with more XSL experience > can point out any obvious errors. > Thanks Victor, To answer your first advise: yes I have full control over the XML files, so I could decide to split up all information into separate elements (most of my XML work is just experimental). However, there are reasons why I sometimes delibarately choose not to do so. In the case I presented as an example, I wanted to do something with the first character of some element, typically to create an index or something alike. In another case I tried to deal with a date, in order to create a birthday calendar. In again another case I wanted to do something with a weeknumber derived from a date from some XML element. What I want to achieve is to construct XML files as simple as possible and then, when need arise, create XSL transformation sheets for specific purposes. Actually, when I am designing some XML format, I dont want to take into account all possible uses I might make of it. It is exactly this what makes XML so attractive to me. Naturally, since my XML formats are not optimized on any specific use, my XSL stylesheets may from time to time be somewhat complex. The second part of your comment is something that needs more thinking, so I cannot answer you instantly. I will study it and reply when I have done so (these are things that I have to do in my spare time, mostly weekends). I greatly appreciate the neat solution you found for a common problem. When I ever find something that may be as usefull as your TIP I certainly will post it the way you did. Piet | ||||||
| Company | Legal | Press | Partners | Careers | Sitemap | Contact Us | Altova Blog | Mobile | Full Site | |||
|
