This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: find Unique Nodes based on 2 Attributes
- To: XSL List <xsl-list at lists dot mulberrytech dot com>
- Subject: Re: [xsl] find Unique Nodes based on 2 Attributes
- From: Joerg Pietschmann <joerg dot pietschmann at zkb dot ch>
- Date: Tue, 23 Oct 2001 09:31:48 +0200
- Organization: ZKB
- Reply-To: xsl-list at lists dot mulberrytech dot com
"cutlass" <cutlass@secure0.com> wrote
> why not use an 'and' to connect 2 tests together ?
for the problem:
> From: "Damian Mcbride" <damian.mcbride@anam.com>
> > I can select a unique node when it is based on one attribute value, but
> when
> > I try to do this with two attribute values I run in to trouble.
> > Example XML
> > <Alert>
> > <Subscriber phonenumber="001" language="fr" alertmethod="SMS"/>
> > <Subscriber phonenumber="002" language="en" alertmethod="SMS"/>
> > <Subscriber phonenumber="003" language="en" alertmethod="SMS"/>
> > <Subscriber phonenumber="004" language="de" alertmethod="email"/>
> > <Subscriber phonenumber="005" language="It" alertmethod="NokiaSmart"/>
> > <Subscriber phonenumber="006" language="It" alertmethod="NokiaSmart"/>
> > <Subscriber phonenumber="007" language="de" alertmethod="NokiaSmart"/>
> > <Subscriber phonenumber="008" language="de" alertmethod="SMS"/>
> > </Alert>
Well, as Mr.Kay already noted, the simple aproach may not work.
In detail, the statement
select="Subscriber[ not(@language=following::Subscriber/@language)
and not(@alertmethod=following::Subscriber/@alertmethod)]"
can be reformulated as follows:
select Subscriber
where there is not any following subscriber with the same language attribute
and there is not any following subscriber with the same alertmethod attribute
This means, the first element from the following set
<Subscriber language="It" alertmethod="NokiaSmart"/>
<Subscriber language="It" alertmethod="SMS"/>
<Subscriber language="de" alertmethod="NokiaSmart"/>
will not be selected, as there is both an element with the same
language and (another) element with the same alertmethod. The original
poster probably wanted to filter out elements which have the same
language and alertmethod at the same time.
The statement
select="Subscriber[not( @language=following::Subscriber/@language
and @alertmethod=following::Subscriber/@alertmethod)]"
wont work either for similar reasons.
Mr.Kay gave the usual but somewhat terse hint to use Munchean Grouping.
The key to this technique is to use xsl:key. In this case it has to
be a compound key using the concat() function:
<xsl:key name="Subscriber-by-attr" match="Subscriber"
use="concat(@language,':',@alertmethod)"/>
The key will select all elements with the same pair of language
and alertmethod attributes. In order to get the pairs actually
contained in the document, we select all Subscribers, but attach a
condition that only the Subscriber which is the same as the first
node in the set of nodes with the same language/alertmethod pair
as selected by the key:
select="Subscriber[generate-id()=generate-id(key('Subscriber-by-attr',concat(@language,':',@alertmethod))[1])]"
HTH
J.Pietschmann
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list