This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
RE: (Keys on multiple element types)
- From: "Michael Kay" <michael dot h dot kay at ntlworld dot com>
- To: <xsl-list at lists dot mulberrytech dot com>
- Date: Tue, 5 Feb 2002 09:27:46 -0000
- Subject: [xsl] RE: (Keys on multiple element types)
- Reply-to: xsl-list at lists dot mulberrytech dot com
>
> I'm trying to get to grips with the syntax of keys across
> children with different names....
>
> I'm trying to display the customer name once with a list of
> projects. I can
> get this to work if all of the child nodes of <FILES> have
> the same name,
> e.g. <RECORD>. If however I change them to three different
> names, I need
> to provide alternatives to the key select as below:-
>
> <?xml version="1.0"?>
> <xsl:stylesheet version="1.1"
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
>
> <xsl:output method="text"/>
>
> <xsl:key name="rows" match="RECORDA | RECORDB | RECORDC" use="name"/>
Fine so far.
>
> <xsl:template match="FILES">
> <xsl:apply-templates
> select="RECORDA[generate-id(.)=generate-id(key('rows',
> name)[1])]"/>
> </xsl:template>
You're processing every RECORDA that is the first (RECORDA|RECORDB|RECORDC)
with that name.
>
> This outputs:-
>
> Fred
> Project 1
> Project 2
>
> But no Harry. So its as if it doesn't include RECORDC in the key list.
>
> q1. Whats wrong with the stylesheet that it doesnt do this. I
> think its :-
> select="RECORDA[generate-id(.
>
> but every other path I try ends up with no output.
If you only select RECORDA elements then it's only going to output RECORDA
elements. If you want RECORDB and RECORDC as well, then use:
select="(RECORDA|RECORDB|RECORDC)
[generate-id(.)=generate-id(key('rows',name)[1])]"
or just:
select="*[generate-id(.)=generate-id(key('rows',name)[1])]"
>
> q2. Does the vertical bar | mean 'or', and wouldnt it be
> better to use ','
> which I think means 'and'? When I tried ',' it threw up loads
> of exceptions.
No it doesn't mean "or", and "," doesn't mean "and". "|" means union. (Where
are you getting your misinformation from?)
>
> q.3 If the xml looked like this instead...
>
> <FILES>
> <RECORDA>
>
> <id>13</id><name>Fred</name><project_name>Building</project_name>
> </RECORDA>
> <RECORDA>
>
> <id>14</id><name>Fred</name><project_name>Building</project_name>
> </RECORDA>
> <RECORDB>
>
> <id>15</id><name>Fred</name><project_name>Looking</project_name>
> </RECORDB>
> <RECORDC>
>
> <id>16</id><name>Harry</name><project_name>Writing</project_name>
> </RECORDC>
> </FILES>
>
>
> How could I get the result to remove multiple copies e.g. to output
> <id>13</id> but not <id>14</id>
>
The code you are using is specifically design to remove duplicates. It looks
to me as if you are using the Muenchian grouping technique "by rote", having
copied it from a cookbook, but without really understanding it. Go back to
the textbook and work through it to understand how it works.
Michael Kay
Software AG
home: Michael.H.Kay@ntlworld.com
work: Michael.Kay@softwareag.com
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list