Re: [xsl] Selecting multi-existant elements only once

Subject: Re: [xsl] Selecting multi-existant elements only once
From: Joerg Heinicke <joerg.heinicke@xxxxxx>
Date: Mon, 25 Nov 2002 18:25:15 +0100
Tom already said, that you can use keys, which I prefer in general. But even without them your code can be optimized. Sorry, but you chosed the poorest one ;-)

<xsl:for-each select="//departement/profession[not(desc=preceding::desc)]">

For *every* node on *every* level (independent of some processor specific optimizations) the conditions will be evaluated. This means every node will be tested for:


- name is profession
- parent is departement
- the string value of a node desc is compared to again *every* preceding node on *every* level with name desc


If you change it only a bit, the code will at least in larger lists much faster:

<xsl:for-each select="/departement/profession[not(desc = preceding-sibling::profession/desc)]">

The removing of the '//' reduces the <profession> elements exactly to only the elements on the second "level" (there is no "level" in XML, but I think you know what I mean: only one ancestor element). And the using of preceding-sibling axis reduces the necessary tests in the predicate more or less enormously, because you can tell the processor exactly where to find the desc elements and again it must not search them on every "level".

At the end the key solution:

<xsl:key name="professions" match="profession" use="desc"/>

<xsl:for-each select="/department/profession[generate-id() = generate-id(key('professions', desc))]">
<xsl:value-of select="."/>
</xsl:for-each>


Regards,

Joerg

I wrote:
Hi all,

I've got a XML-File with following structure. There are different departements and in each departement there are different professions. I want to have every profession of all departement once... If there is a Manager in departement a and departement b, "Manager" should only be printed out once...

How can I do that?

[...]
<departement>
 <profession>
   <desc>Manager</desc>
   <salary>5000</salary>
 </profession>

 <profession>
   <desc>Assistant</desc>
   <salary>3000</salary>
 </profession>

 <profession>
   <desc>Employee</desc>
   <salary>2000</salary>
 </profession>
</departement>

<departement>
 <profession>
   <desc>Manager</desc>
   <salary>5000</salary>
 </profession>

 <profession>
   <desc>Worker</desc>
   <salary>2000</salary>
 </profession>
</departement>

[...]

Thanks for your help !

Sorin


XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list


Current Thread