Schleife über Elemente + position()-Funktion
Alex1
- xsl
0 Mia0 Thomas Meinike
Hallo,
ich habe folgende Problemstellung:
In der ersten Schleife "<xsl:for-each select..." gehe ich über alle Gesundheitsfragen in meinem XML-Dokument und prüfe, ob das darin enthaltene Tag "NAntwort=1" ist.
Falls dies der Fall ist, soll eine Tabelle erstellt werden, die weitere Elemente des aktuellen Tags "Gesundheitsfrage" aus gibt.
Soweit funktioniert auch alles...
Mein Problem: Wie ich das erste mal auf das Tag <NAntwort>1</NAntrwort> stoße. möchte ich den Tabellenkopf mit generieren.
Mein Ansatz war der, einfach mit der Funktion position() dies innerhalb der Schleife zu lösen.
Leider liefert mir die Funktion nicht das Ergebnis innerhalb des Schleifen-Contexts sondern das globale Ergebnis der XML-Datei.
Frage: Wie kann ich innerhalb der Schleife unterscheiden, ob ich zum ersten mal auf das Element <NAntwort> mit dem Wert "1" stoße.
Anbei die Logik - bei Bedarf, maile ich auch gerne das XML-File zum besseren Verständnis...
VIELEN DANK!
Alex
<!-- START - Abfrage, ob ein oder mehrere Gesundheitsfragen mit 'ja' beantwortet wurden -->
<xsl:for-each select="PPersonArray/item/VersPerson/PGesundheitsdaten/PGesundheitsfragen/item/Gesundheitsfrage">
<!-- Prüfen, ob das Tag "PGesundheitsdaten/PGesundheitsfragen/item/Gesundheitsfrage/NAntwort"=1 vorhanden ist. Wenn ja, wurden mindestens eine Gesundheitsfrage mit "ja" beantwortet. -->
<xsl:if test="NAntwort='1'">
<!-- <fo:block keep-together="always" text-align="start">TESTAUSGABE - Es wurden Diagnosen erfasst!</fo:block> -->
<!-- ZUERST NOCH PRÜFEN, OB MAN GERADE AN POSITION 1 IST. WENN JA, TABELLENHEADER AUSGEBEN, WENN NEIN, DANN NUR ZEILEN AUSGEBEN -->
fo:block
xsl:choose
<xsl:when test="position()='1'">
<fo:inline font-size="8pt" font-family="Times" font-weight="bold">Tabelle mit HEADER erstellen!</fo:inline>
</xsl:when>
<xsl:when test="position()>'1'">
<fo:inline font-size="8pt" font-family="Times" font-weight="bold">Tabelle ohne HEADER erstellen!</fo:inline>
</xsl:when>
xsl:otherwise
Fehler!
</xsl:otherwise>
</xsl:choose>
</fo:block>
Hallo Alex,
warum prüfst du nicht vorab, ob ein solches Element vorkommt
mit <xsl:if test="...">
und gibst im positiven Fall die Headerinformation vorab aus?
Gruß Mia
Hallo,
das Problem ist, dass das Element immer vorkommt, nur mit verschiedenen Werten.
Ich prüfe ja, wie Du es auch vorgeschlagen hast mit:
<xsl:if test="NAntwort='1'">
Die fachliche Logik wäre jetzt, nachdem ich ein solches Element zum ersten mal gefunden habe, dass ich jetzt eine Tabelle inklusive Tabellen-Header (Spaltenbezeichnungen etc) ausgeben müsste - UND wenn ich zum 2., 3. etc. mal auf das Element stoße, eben nur eine Zeile an die Tabelle anhängen muss und nicht wieder den Header mit ausgeben darf.
Aus diesem Grund war die Funktion position() mein Ansatz. Leider funktioniert das bei mir nicht ganz so...
Kannst Du mir hiermit irgendwie weiter helfen?
DANKE!
Gruß
Alex
Hallo Alex,
warum prüfst du nicht vorab, ob ein solches Element vorkommt
mit <xsl:if test="...">
und gibst im positiven Fall die Headerinformation vorab aus?Gruß Mia
Hallo Alex,
ich dachte an folgende Reihenfolge:
<xsl:if test="NAntwort='1'">
<table>
Ausgabe Header
xsl:for-each... wie bisher
Ausgabe Zeile
</xsl:for-each>
</table>
</xsl:if>
Möglicherweise habe ich dich aber auch grundsätzlich falsch verstanden.
Gruß Mia
Hallo Mia,
vielen Dank für Deine Antwort.
In einem weiterem Forum habe ich die Antwort für mein Problem gefunden:
count(PPersonArray/item/NAnswer[. = 1])
Gruß
Alex
Hallo Alex,
warum prüfst du nicht vorab, ob ein solches Element vorkommt
mit <xsl:if test="...">
und gibst im positiven Fall die Headerinformation vorab aus?Gruß Mia
Hallo,
Mein Ansatz war der, einfach mit der Funktion position() dies innerhalb der Schleife zu lösen.
Leider liefert mir die Funktion nicht das Ergebnis innerhalb des Schleifen-Contexts sondern das globale Ergebnis der XML-Datei.
Prinzipieller Hinweis: Verabschiede Dich von der Schleifen-Denkweise. xsl:for-each ist eine Mehrfach-Verarbeitungsanweisung. Der Begriff Schleife suggeriert, dass ein Codeblock nacheinander immer wieder von oben herab durchlaufen wird. Der Code von xsl:for-each wandert aber durch die XML-Baumstruktur (die Verarbeitung erfolgt ggf. sogar parallel). "Gefuehlsmaeßig" ist das mit einer Schleife vergleichbar, technisch nicht.
Anbei die Logik - bei Bedarf, maile ich auch gerne das XML-File zum besseren Verständnis...
Ja bitte, das fehlt zum Verstaendnis der Logik.
<xsl:when test="position()='1'">
Hier faellt zumindest auf, dass ein von position() ermittelter numerischer Wert mit einem String verglichen wird. test="position()=1" passt besser (auch wenn evtl. implizit eine Typkonvertierung erfolgt).
Vermutung: Das Problem laesst sich gaenzlich ohne xsl:for-each loesen, wenn mehrere xsl:template-Vorlagen mittels xsl:apply-templates aufgerufen werden.
MfG, Thomas