Home. 
.

transparent

transparent

transparent

Altova Mailing List Archives


Re: Tip: Finding & counting unique nodes in XSL

From: Piet Blok <p@->
To: 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



transparent
Print
Mail
Like It
Disclaimer
.

These Archives are provided for informational purposes only and have been generated directly from the Altova mailing list archive system and are comprised of the lists set forth on www.altova.com/list/index.html. Therefore, Altova does not warrant or guarantee the accuracy, reliability, completeness, usefulness, non-infringement of intellectual property rights, or quality of any content on the Altova Mailing List Archive(s), regardless of who originates that content. You expressly understand and agree that you bear all risks associated with using or relying on that content. Altova will not be liable or responsible in any way for any content posted including, but not limited to, any errors or omissions in content, or for any losses or damage of any kind incurred as a result of the use of or reliance on any content. This disclaimer and limitation on liability is in addition to the disclaimers and limitations contained in the Website Terms of Use and elsewhere on the site.

.
.

transparent

transparent