Re: [xsl] xslt count distinct values - X3D

Subject: Re: [xsl] xslt count distinct values - X3D
From: "Andrew Welch" <andrew.j.welch@xxxxxxxxx>
Date: Wed, 13 Aug 2008 10:52:07 +0100
2008/8/13 j milo taylor <milo@xxxxxxxxxx>:
> I need to count the distinct <Country> values from this XML and this to be
> assigned to the 'size'; dattribute of a <Box> element in X3D
>
> The XML (fragment example)/////////////////////////////////////////
>
> <Artists_by_Countries>
>
>   <Artist_by_Country>
>       <Location_ID>62</Location_ID>
>       <Artist_ID>212</Artist_ID>
>       <Country>Argentina</Country>
>   </Artist_by_Country>
>
>    <Artist_by_Country>
>       <Location_ID>4</Location_ID>
>       <Artist_ID>108</Artist_ID>
>       <Country>Australia</Country>
>   </Artist_by_Country>
>
>    <Artist_by_Country>
>       <Location_ID>4</Location_ID>
>       <Artist_ID>111</Artist_ID>
>       <Country>Australia</Country>
>   </Artist_by_Country>
>
>   <Artist_by_Country>
>       <Location_ID>12</Location_ID>
>       <Artist_ID>78</Artist_ID>
>       <Country>Germany</Country>
>   </Artist_by_Country>
>
> </Artists_by_Countries>
>
> I've been using this XSLT, but getting nowhere (the Muenchian Method??)
> (using Netbeans)
>
> XSLT///////////////////////////////////////////psuedo
>
> <xsl:key name="artists-by-country" match="Artist_by_Country" use="Country"
> />
> ..
> ..
> ..
>   <xsl:template match="Artists_by_Countries">
>       <xsl:for-each select="Artist_by_Country[count(. |
> key('artists-by-country', Country)[1]) = 1]">


The "Muenchian Method" gets distinct values by ignoring all values
unless they are the first occurrence of that value.  So to get a
distinct list of countries you need to do:

select="Artist_by_Country[generate-id(.) =
generate-id(key('artists-by-country', Country)[1])]"

This looks a bit mad, but it's really simple - the main concept to get
is the call to the key:

key('artists-by-country', Country)

 The <Country> is passed to the key, say "Australia", which returns
two nodes as there are two <Artist_by_Country> elements with a country
of Australia.

key('artists-by-country', Country)[1]

The [1] picks the first of the list

generate-id(.) = generate-id(...)

The generate-id(.) = generate-id(...) part is testing to see if the
nodes are the same nodes, as in the same individual node in the input
tree.  Nodes with the same name and value would not pass this test.
In 2.0 the "is" operator can be used instead, which is a little
clearer.

So altogether:

Artist_by_Country[generate-id(.) =
generate-id(key('artists-by-country', Country)[1])]

For the all the various values of <Country> the above XPath will give
the first occurrence of each, which is your list of distinct values.

>               <xsl:attribute name ='size'>
>                                   <xsl:value-of=" KEY COUNT OF DISTINCT
> COUNTRY VALUES>

I'm not too sure what you want here, but if it's say 2 for "Australia"
in your example then you just need:

count(key('artists-by-country', Country))


cheers
-- 
Andrew Welch
http://andrewjwelch.com
Kernow: http://kernowforsaxon.sf.net/

Current Thread