Baum zur Tranformierung anlegen
André Laugks
- xsl
0 MudGuard0 André Laugks0 MudGuard0 André Laugks0 MudGuard
0 Thomas J.S.
Hallo!
Ich habe folgendes XML-Dokument gegeben. Ich möchte damit folgendes machen. Es soll nach den Namen sortiert werden und zu jedem Namen dessen Vorgänger und Nachfolger ermittelt werden. Das Problem ist, bei der Ermittlung des Vorgängers und Nachfolgers, wird die Reihenfolge der Elemente im XML-Dokumentes verwendet und nicht die sortierte Reihenfolge.
Das Dokument mit dem ich experimentiere ist viel viel viel umfangreicher als das hier aufgeführte. Kann ich ein virtuelles XML-Dokument generieren bzw. Teilbäume virtuell extrahieren und zusammen fassen, mit denen ich arbeiten kann? Ich baue also für die Tranformierungsvorgang virtuell ein Dokument bzw. Baum auf, in dem alle Element "eintrag" sortiert nach dem Element "name" stehen. In diesem Baum kann ich dann schön den Vorgänger und Nachfolger ermitteln.
<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet href="zappen.xsl" type="text/xsl"?>
<liste>
<eintrag id="10">
<name>Berta</name>
</eintrag>
<eintrag id="3">
<name>Anton</name>
</eintrag>
<eintrag id="9">
<name>Dieter</name>
</eintrag>
<eintrag id="12">
<name>Werner</name>
</eintrag>
<eintrag id="17">
<name>Gerd</name>
</eintrag>
<eintrag id="8">
<name>Christian</name>
</eintrag>
<eintrag id="6">
<name>Lisa</name>
</eintrag>
<eintrag id="5">
<name>Inge</name>
</eintrag>
<eintrag id="16">
<name>Friedrich</name>
</eintrag>
</liste>
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes"/>
<xsl:template match="liste">
<table border="1">
<tr>
<td>Vorgänger</td>
<td>x</td>
<td>Nachfolger</td>
</tr>
<xsl:apply-templates select="eintrag">
<xsl:sort select="name"/>
</xsl:apply-templates>
</table>
</xsl:template>
<xsl:template match="eintrag">
<tr>
<td><xsl:value-of select="preceding-sibling::eintrag[1]/name"/></td>
<td><xsl:value-of select="name"/></td>
<td><xsl:value-of select="following-sibling::eintrag[1]/name"/></td>
</tr>
</xsl:template>
</xsl:stylesheet>
MfG, André Laugks
Hi,
Ich habe folgendes XML-Dokument gegeben. Ich möchte damit folgendes machen. Es soll nach den Namen sortiert werden und zu jedem Namen dessen Vorgänger und Nachfolger ermittelt werden. Das Problem ist, bei der Ermittlung des Vorgängers und Nachfolgers, wird die Reihenfolge der Elemente im XML-Dokumentes verwendet und nicht die sortierte Reihenfolge.
<xsl:template match="eintrag">
<tr>
<td><xsl:value-of select="preceding-sibling::eintrag[1]/name"/></td>
kein Wunder, die sibling-Teile gehen auf die Dokumentstruktur.
Verwende position() - laß Dir das Element mit der aktuellen position() - 1 und das mit der aktuellen position() + 1 auswählen.
cu,
Andreas
Hallo!
wird die Reihenfolge der Elemente im XML-Dokumentes verwendet und nicht die sortierte Reihenfolge.
kein Wunder, die sibling-Teile gehen auf die Dokumentstruktur.
Das habe ich ja auch schon fest gestellt bzw. ist mir klar.
Verwende position() - laß Dir das Element mit der aktuellen position() - 1 und das mit der aktuellen position() + 1 auswählen.
Soweit war ich auch schon, nur irgendwie kommt nichts.
<xsl:template match="eintrag">
<tr>
<td><xsl:value-of select="position()"/></td>
<td><xsl:value-of select="../eintrag[position() - 1]/name"/></td>
<td><xsl:value-of select="name"/></td>
<td><xsl:value-of select="../eintrag[position() + 1]/name"/></td>
</tr>
</xsl:template>
Wenn ich anstatt der XPath-Audrücke "../eintrag[position() - 1]/name" oder "../eintrag[position() + 1]/name" den XPath-Ausdruck "../eintrag/name" schreibe, bekomme ich wie erwartet "Berta", also das erste Element "eintrag/name" aus dem XML-Dokument. Der Pfad stimmt also.
MfG, André Laugks
Hi,
<td><xsl:value-of select="../eintrag[position() - 1]/name"/></td>
Müßte m.E. so lauten (ungetestet):
../eintrag[position() = (./position()-1)
cu,
Andreas
Hallo!
Müßte m.E. so lauten (ungetestet):
../eintrag[position() = (./position()-1)
Nein, das Funktioniert nicht. Der Prozessor regt sich über "./" auf.
Folgende Konstrukt liefert mir aber auch nur die Reihenfolge des XML-Dakumentes, für den Vorgänger und Nachfolger.
<xsl:template match="eintrag">
<xsl:variable name="v">
<xsl:value-of select="position() + 1"/>
</xsl:variable>
<xsl:variable name="z">
<xsl:value-of select="position() - 1"/>
</xsl:variable>
<tr>
<td><xsl:value-of select="$z"/></td>
<td><xsl:value-of select="$v"/></td>
<td><xsl:value-of select="position()"/></td>
<td><xsl:value-of select="../eintrag[position() = $z]/name"/></td>
<td><xsl:value-of select="name"/></td>
<td><xsl:value-of select="../eintrag[position() = $v]/name"/></td>
</tr>
</xsl:template>
Hier lass ich ja die Variablen mitlaufen. Die Werte sind wie erwartet. Schreibe ich nun aber z.B. "../eintrag[position() = $v]/name" um in "../eintrag[$v]/name" bekomme ich immer nur Berta angezeigt, also der erste Name im XML-Dokument. Schreibe ich aber für $v eine Zahl rein, also 1, 2, 3, 4 usw. ("../eintrag[2]/name" -> Anton), bekomme ich immer den betreffenden Namen zurück, wie erwartet.
MfG, André Laugks
Hi,
<td><xsl:value-of select="../eintrag[position() = $z]/name"/></td>
War das nicht ${v} ?
Hab zu lange kein XSL mehr gemacht...
cu,
Andreas
Hallo Andreas,
<td><xsl:value-of select="../eintrag[position() - 1]/name"/></td>
Müßte m.E. so lauten (ungetestet):
../eintrag[position() = (./position()-1)
Kann nicht gehen.
<td><xsl:value-of select="position()"/></td> liefert die Position die "eintrag" beim sortieren bekommt.
Alle anderen konstrukte mit position() beziehen sich aber auf die tatsächliche Position vom "eintrag" im Dokument.
Grüße
Thomas