Hallo,
Also die XML-Struktur haut so hin:
Na gut. Also dann eben so:
<?xml version="1.0" encoding="ISO-8859-1"?>
<test>
<Schicht1>
<Schicht2>
<Schichtnummer>123</Schichtnummer>
<Schicht3>
<Schicht4>
<Schichtnummer>20</Schichtnummer>
<Schicht5>
<Schichtnummer>2</Schichtnummer>
</Schicht5>
</Schicht4>
</Schicht3>
</Schicht2>
</Schicht1>
</test>
Nun zum XSL:
Du hast wieder nur den mehr oder wenigen (un)sinnigen Kodeschnipsel gepostet, der schon vorher da war.
Aber gucken wir mal....
Über ein Dropdown-Menü kann die Schicht ausgewählt werden.
- wo steht dieses for-each denn!? Sprich: was ist das Element in dessen Templates es steht? (wobei das insofern irrelevant ist, da du immer vom "//" ausgehst)
- was ist $positionsnummer? Sprich woher bekommst das for-each sie denn und was steht drinn?
3) Wenn es ein Dropdown-Menü sein soll, warum postest deinen Kode nicht so, dass man darin sehe kann was du machst?
(glaube mir, keiner ist hier an den Buchstaben deines XML/XSLT interessiert, am allerwenigsten ich, aber wenn du nichts sagst ist es nunmal ein "im Glaskugel gucken", da kann man dir nicht helfen!)
Wenn in dieser Schicht eine Schichtnummer exitier soll sie ausgegeben werden. SIehe hier:
<xsl:for-each select="//child::*[contains(local-name(), 'Schicht')]">
<xsl:if test="position() = $positionsnummer">
xsl:choose
<xsl:when test="boolean(Schichtnummer)">
<xsl:for-each select="//child::*[contains(local-name(), 'Schicht')]">
<xsl:if test="position() = $positionsnummer">
<xsl:value-of select="Schichtnummer"></xsl:value-of>
Und was soll das bewirken, außer gar nichts?
Du macht zwei mal dasselbe, weil du beide mal vom Wurzelelement ausgehst "//child::*"
Was du hier machst ist folgendes:
- Suche mir alle Kindelemente eines Elements ausgehend vom Wurzelelement in dessen Namen "Schicht" vorkommt. (sprich du machst nichts anderes als: //*[...])
angewendet auf dein XML:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/test">
<html>
<head>
<title>Untitled</title>
</head>
<body>
<xsl:for-each select="//*[contains(local-name(), 'Schicht')]">
<<xsl:value-of select="local-name()" />>
<br />
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Ergebniss:
<Schicht1>
<Schicht2>
<Schichtnummer>
<Schicht3>
<Schicht4>
<Schichtnummer>
<Schicht5>
<Schichtnummer>
sprich: du hast brav alle Elemente ausgewählt.
-
Teste ob "position() = $positionsnummer" ist.
Tja, ich weiss aber nicht, was bei dir in der Variable "$positionsnummer" steht, denn das sagst du nicht.
Aber die Positionen deiner Elemente von deinem XML-Beispiel schaut so aus:
<Schicht1>:1
<Schicht2>:2
<Schichtnummer>:3
<Schicht3>:4
<Schicht4>:5
<Schichtnummer>:6
<Schicht5>:7
<Schichtnummer>:8
-
wenn also "position() = $positionsnummer" ist, teste ob im aktuellen Element ein Kindelement "Schichtnummer" gibt. (Dazu reicht übrigens <xsl:when test="Schichtnummer"> aus.)
Laut deiner Aussage soll hier die Schichtnummer ausgegeben werden. Machst du aber nicht, sonder:
- du sagst wie beim Schritt 1: Suche mir alle Kindelemente eines Elements ausgehend vom Wurzelelement in dessen Namen "Schicht" vorkommt. (sprich du machst nichts anderes als: //*[...]) und selektierst wieder alle Elemente)
Wenn du jetzt anschaust was du macht: (ich habe hier $positionsnummer eingeführt)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/test">
<html>
<head>
<title>Untitled</title>
</head>
<body>
<xsl:for-each select="//[contains(local-name(), 'Schicht')]">
<xsl:variable name="positionsnummer" select="position()" />
<<xsl:value-of select="local-name()" />>:<xsl:value-of select="position()" />:<xsl:value-of select="$positionsnummer" />
<xsl:if test="position() = $positionsnummer">
xsl:choose
<xsl:when test="Schichtnummer">
<xsl:for-each select="//[contains(local-name(), 'Schicht')]">
<br />
<<xsl:value-of select="local-name()" />>:<xsl:value-of select="position()" />:<xsl:value-of select="$positionsnummer" />
</xsl:for-each>
</xsl:when>
</xsl:choose>
</xsl:if>
<br />
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Hast du gerade: (El.Name : aktuelle Position : gespeicherte Pos.)
<Schicht1>:1:1
<Schicht2>:2:2
<Schicht1>:1:2
<Schicht2>:2:2
<Schichtnummer>:3:2
<Schicht3>:4:2
<Schicht4>:5:2
<Schichtnummer>:6:2
<Schicht5>:7:2
<Schichtnummer>:8:2
<Schichtnummer>:3:3
<Schicht3>:4:4
<Schicht4>:5:5
<Schicht1>:1:5
<Schicht2>:2:5
<Schichtnummer>:3:5
<Schicht3>:4:5
<Schicht4>:5:5
<Schichtnummer>:6:5
<Schicht5>:7:5
<Schichtnummer>:8:5
<Schichtnummer>:6:6
<Schicht5>:7:7
<Schicht1>:1:7
<Schicht2>:2:7
<Schichtnummer>:3:7
<Schicht3>:4:7
<Schicht4>:5:7
<Schichtnummer>:6:7
<Schicht5>:7:7
<Schichtnummer>:8:7
<Schichtnummer>:8:8
- jetzt sagt du wieder: teste ob "position() = $positionsnummer" ist und wenn ja, gib "Schichtnummer" aus.
Ändern wir den Teil des XSLs dementsprechend:
xsl:choose
<xsl:when test="Schichtnummer">
<xsl:for-each select="//*[contains(local-name(), 'Schicht')]">
<br />
<xsl:if test="position() = $positionsnummer">
   <<xsl:value-of select="local-name()" />>:<xsl:value-of select="position()" />:<xsl:value-of select="$positionsnummer" />:<xsl:value-of select="Schichtnummer" />
</xsl:if>
</xsl:for-each>
</xsl:when>
</xsl:choose>
Ergebniss:
<Schicht1>:1:1
<Schicht2>:2:2
<Schicht2>:2:2:123
<Schichtnummer>:3:3
<Schicht3>:4:4
<Schicht4>:5:5
<Schicht4>:5:5:20
<Schichtnummer>:6:6
<Schicht5>:7:7
<Schicht5>:7:7:2
<Schichtnummer>:8:8
Wie du siehst, bekommst du schon hier alle Schichtnummern ausgegeben. Ich hoff dir ist es nun auch klar warum.
Dann gehst du aber noch einen Schritt weiter:
- und sagst als Gegensatz zu Schritt 3: wenn im aktuellen Element kein Kindelement "Schichtnummer" gibt, ...
XSL-Teil angepasst:
xsl:choose
<xsl:when test="Schichtnummer">
<xsl:for-each select="//[contains(local-name(), 'Schicht')]">
<br />
<xsl:if test="position() = $positionsnummer">
<<xsl:value-of select="local-name()" />>:<xsl:value-of select="position()" />:<xsl:value-of select="$positionsnummer" />:<xsl:value-of select="Schichtnummer" />
</xsl:if>
</xsl:for-each>
</xsl:when>
<xsl:when test="not(Schichtnummer)">
<xsl:for-each select="//[contains(local-name(), 'Schicht')]">
<br />
<xsl:if test="position() > $positionsnummer">
-<<xsl:value-of select="local-name()" />>:<xsl:value-of select="position()" />:<xsl:value-of select="$positionsnummer" />:<xsl:value-of select="Schichtnummer" />
</xsl:if>
</xsl:for-each>
</xsl:when>
</xsl:choose>
Ergebnis:
<Schicht1>:1:1
-<Schicht2>:2:1:123
-<Schichtnummer>:3:1:
-<Schicht3>:4:1:
-<Schicht4>:5:1:20
-<Schichtnummer>:6:1:
-<Schicht5>:7:1:2
-<Schichtnummer>:8:1:
<Schicht2>:2:2
<Schicht2>:2:2:123
<Schichtnummer>:3:3
-<Schicht3>:4:3:
-<Schicht4>:5:3:20
-<Schichtnummer>:6:3:
-<Schicht5>:7:3:2
-<Schichtnummer>:8:3:
<Schicht3>:4:4
-<Schicht4>:5:4:20
-<Schichtnummer>:6:4:
-<Schicht5>:7:4:2
-<Schichtnummer>:8:4:
<Schicht4>:5:5
<Schicht4>:5:5:20
<Schichtnummer>:6:6
-<Schicht5>:7:6:2
-<Schichtnummer>:8:6:
<Schicht5>:7:7
<Schicht5>:7:7:2
<Schichtnummer>:8:8
Jetzt hast du also die Schichtnummer noch mal mehrfach.
das geht auch alles, nun soll aber die erste Schichtnummer ausgegeben werde die gefunden wird, da ich nur die Schichtnummer haben will, die in der am nächsten darunterliegenden Schicht haben will.
Ich bekomme aber immer alle. Ich kann aber an der for-each nichts ändern, da dann das Prinzip mit meiner Positionsnummer nicht mehr geht!
Ich weiss bzw. versteh beim besten Willen nicht, was du vorhast. Was ist das Prinzig deiner "Positionsnummer "?. Bzw. mir ist das zu konfus was du erzählst.
Wenn ich von dem Beispiel XML von oben ausgehe soll nach deiner Aussage:
Beim Schicht1 soll die Schichtnummer aus Schicht1 angezeigt werden.
Beim Schicht2 soll die (eigene) Schichtnummer angezeigt werden.
Beim Schicht3 soll die Schichtnummer aus Schicht4 angezeigt werden.
Beim Schicht4 soll die (eigene) Schichtnummer angezeigt werden.
Beim Schicht5 soll die (eigene) Schichtnummer angezeigt werden.
Dafür ist ein rekursives Template besser geeignet:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/test">
<html>
<head>
<title>Untitled</title>
</head>
<body>
<xsl:apply-templates select="*[contains(local-name(), 'Schicht')]" />
</body>
</html>
</xsl:template>
<xsl:template match="[contains(local-name(), 'Schicht')]">
xsl:choose
<xsl:when test="Schichtnummer">
<<xsl:value-of select="local-name(.)" />>:<xsl:value-of select="Schichtnummer" />
<br />
</xsl:when>
xsl:otherwise
<xsl:if test="">
<<xsl:value-of select="local-name(.)" />>(gefunden im: <<xsl:value-of select="local-name(descendant::[contains(local-name(), 'Schicht')][Schichtnummer])" />>):<xsl:value-of select="descendant::Schichtnummer" />
<br />
</xsl:if>
</xsl:otherwise>
</xsl:choose>
<xsl:apply-templates select="[contains(local-name(), 'Schicht')]" />
</xsl:template>
</xsl:stylesheet>
Egebniss:
<Schicht1>(gefunden im: <Schicht2>):123
<Schicht2>:123
<Schicht3>(gefunden im: <Schicht4>):20
<Schicht4>:20
<Schicht5>:2
Du brauchst nur überall das "<<xsl:value-of select="local-name(.)" ..." löschen. Funktioniert auch bei tieferen Verschachtelung.
Ich hoffe, dass diese das ist was du erreichen wolltest.
Grüße
Thomas