XSLT: Doppelte Einträge in Ergebnis-Datei vermeiden?
-
Hallo,
kennt sich hier vielleicht jemand mit XSLT aus? Ich hänge gerade nämlich an folgendem Problem:
Angenommen ich habe eine XML-Datei mit einem Haufen Datensätzen, z.B. sowas hier:
... <person> <name>Müller</name> <vorname>Petra</vorname> <alter>12</alter> ... </person> <person> <name>Müller</name> <vorname>Anton</vorname> <alter>12</alter> ... </person> <person> <name>Schmidt</name> <vorname>Tina</vorname> <alter>18</alter> ... </person>
So ein Ergebnis mit XSLT zu generieren wäre ja kein Problem:
Müller, 12 Müller, 12 Schmidt, 18
Ich würde jetzt aber gerne mit XSLT-Bordmitteln so etwas erzeugen:
Müller, 12 Schmidt, 18
Also, im Prinzip genau das, was "SELECT DISTINCT" in SQL macht.
Hat jemand eine Idee wie sich so etwas mit XSLT realisieren lässt?
Grüße,
Michael
-
Google hat da eine Menge Ideen.
Für XSLT 1.0 ist es relativ umständlich, aber eine höhere Version der XSLT kann das von sich aus. Nach XSLT und Distinct googeln bringt dich weiter
-
Danke! Mit einfachen Keys klappt das jetzt schon ganz gut. Aber jetzt komme ich schon wieder nicht weiter: Was, wenn ein Key für einen Knoten aus vielen Kind-Attributen zusammengebaut werden soll?
Die XML-Datei könnte z.B. so aussehen (sorry, ist ein bisschen konstruiert, aber ich denke das Problem wird klar):
<garten> <apfelbaum name = "Baum1"> <obst name="m" /> <blatt name="," /> <obst name="b"/> <obst name="c"/> <blatt name="," /> <obst name="d"/> </apfelbaum> <apfelbaum name = "Baum2"> <obst name="m" /> <blatt name="," /> <obst name="b"/> <obst name="c"/> <blatt name="," /> <obst name="d"/> </apfelbaum> <apfelbaum name = "Baum3"> <obst name="o" /> <blatt name="g" /> <obst name="h"/> <obst name="c"/> <blatt name="," /> <obst name=","/> </apfelbaum> </garten>
Der Key soll sich nun aus den zusammengesetzten Name-Attributen der Kind-Elemente zusammensetzen, sodass z.B. der Key für "Baum1" ist: m,bc,d
Die für "Baum2": m,bc,d
Die für "Baum3": oghc,,Sodass die Ausgabe dann wäre:
m,bc,d oghc,,
D.h., Baum1 und Baum2 würden eine Gruppe bilden und Baum3 würde eine Gruppe bilden.
Bisherige Überlegung:
<xsl:key name="remove-duplicates" match="apfelbaum" use="obst/@name | blatt/@name"/> <xsl:template match="garten"> <xsl:for-each select="apfelbaum[count(. | key('remove-duplicates', "obst/@name | blatt/@name)[1]) = 1]"> <xsl:value-of select="@name"/> </xsl:for-each> </xsl:template>
Funktioniert aber nicht. Die Reihenfolge der Symbole des Keys ist wichtig, das klappt mit der Methode oben nicht.
Danke im voraus,
MichaelEdit: Achso, ich würde das gerne in XSLT 1.0 machen.
-
Ok, das Problem nochmal anders aufgezogen:
<xsl:key name="remove-duplicates" match="apfelbaum" use="count(obst)" />
Das "count" an der Stelle wird korrekt ausgewertet. Ich kriege da also keine 1, sondern eine 3 oder 4. D.h. an der Stelle werden korrekt alle Obst-Namen zurückgeliefert.
<xsl:key name="remove-duplicates" match="apfelbaum" use="obst/@name" />
Das hingegen liefert mit nur das 'name'-Attribut des erste Obst-Elements. Ich kann aber auch z.B. auf das zweite zugreifen:
<xsl:key name="remove-duplicates" match="apfelbaum" use="obst[2]/@name" />
Aber wie bekomme ich es an der Stelle jetzt hin, dass er alle 'name'-Attribut der Kind-Obst-Elemente verwendet und einfach nacheinander als String hinschreibt?
Edit: Oder anders gesagt ist das Problem eigentlich: Gibt es eine Funktion, die für ein node-set folgendes macht: concat(name(node_1), ..., name(node_n))
Grüße,
Michael