1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen

XSL: Zähler der "matched"

Dieses Thema im Forum "XML Technologien" wurde erstellt von FSP, 21. Juli 2014.

  1. FSP

    FSP Grünschnabel

    Hallo an alle, die sich mit XSL auskennen (und an alle anderen natürlich auch :)):

    VORWORT
    In meiner Verzweiflung wende ich mich an Euch, bevor ich mich aufhänge. [​IMG]
    Es geht um das alte Thema "Zähler" in XSL-Dateien. Natürlich habe ich schon stundenlang gegoogelt und schon alles mögliche ausprobiert, bin aber immer nur auf die gleichen falschen Beispiele gestoßen, und niemand scheint das Problem zu haben, das ich habe.

    WAS WILL ICH MACHEN?
    Ich will in einem E-Book Aufzählungen (Listen) manuell setzen, also nicht mit <OL> und <UL> arbeiten. Sind Aufzählungen aber geschachtelt, haben also eine erste und dann eine zweite eingezogene Hierarchie, muss ich einen Hierarchiezähler anlegen, damit das HTML-Dokument weiß, dass es die erste Hierarchie nicht einziehen soll, die zweite aber schon.
    In meiner XML-Datei habe ich dazu für die Tags <AUFZ> gesorgt, die immer eine ganze Aufzählung umschließen. Also sieht die Struktur einer geschachtelten Aufzählung bei mir folgendermaßen aus:
    <AUFZ>Nicht eingezogener Aufzählungstext inkl. anderer Tags
    <AUFZ>Eingezogener Aufzählungstext inkl. anderer Tags
    </AUFZ>
    Nicht eingezogener Aufzählungstext inkl. anderer Tags
    </AUFZ>

    WAS IST DAS PROBLEM?
    Das Problem ist, dass in XSL Variablen Konstanten sind, also so einfach wie in der Basic-Sprache nicht von alleine weiterzählen, also funktioniert es natürlich nicht, wenn ich innerhalb eines <xsl:template match="AUFZ"> ein <xsl: param name="zaehler" select="$zaehler+1"/> setze, denn dann zählt nix.
    Und wenn ich das hier mache:

    <xsl:template name="loop">
    <xsl: param name="zaehler"/>
    <xsl: param name="limit"/>
    <xsl:if test="$zaehler &lt;= $limit">
    <xsl:choose>
    <xsl:when test="$zaehler=1">
    <div class="aufzaehlung1"><xsl:apply-templates/></div>
    </xsl:when>
    <xsl:when test="$zaehler=2">
    <div class="aufzaehlung2"><xsl:apply-templates/></div>
    </xsl:when>
    </xsl:choose>
    <xsl:call-template name="loop">
    <xsl:with-param name="zaehler" select="$zaehler+1"/>
    <xsl:with-param name="limit" select="$limit"/>
    </xsl:call-template>
    </xsl:if>
    </xsl:template>

    <xsl:template match="AUFZ">
    <xsl:call-template name="loop">
    <xsl:with-param name="zaehler" select="0"/>
    <xsl:with-param name="limit" select="10"/>
    </xsl:call-template>
    </xsl:template>

    ...dann durchläuft er zehnmal die Schleife und arbeitet jeden Zählerstand ab, also trifft einmal den Zähler=1 und dann nochmal Zähler=2 und macht dann alles doppelt. Er trifft also nicht wirklich eine Entscheidung.

    Und wenn ich das da mache (hier habe ich noch zusätzlich einen <AUFZ2> hinter jeden <AUFZ> gesetzt):

    <xsl:template match="AUFZ">
    <xsl:for-each select="AUFZ2">
    <xsl:variable name="zaehler" select="position()"/>
    <xsl:choose>
    <xsl:when test="$zaehler=1">
    <div class="aufzaehlung1"><xsl:apply-templates/></div>
    </xsl:when>
    <xsl:when test="$zaehler=2">
    <div class="aufzaehlung2"><xsl:apply-templates/></div>
    </xsl:when>
    </xsl:choose>
    </xsl:for-each>
    </xsl:template>

    ...nützt es auch nichts, denn dann zählt er immer nur bis 1, weil er offensichtlich irgendwie immer nur ganze Templates zählt und nicht in sich geschachtelte.

    UND NUN DIE FRAGE
    Wie kann ich einen Hierarchiezähler programmieren, der quasi jeden ANFANGSTAG eines Templates zählt, so dass es auch im geschachtelten Zustand funktioniert?


    Für jede Antwort wäre ich sehr dankbar.

    Gruß
    Thomas
     
  2. hela

    hela Premium-User

    Zuletzt bearbeitet: 21. Juli 2014
  3. FSP

    FSP Grünschnabel

    Hallo Hela!

    Vielen Dank für den Tipp. :)
    Das werde ich mir jetzt mal anschauen bzw. mich da durchkämpfen.

    Liebe Grüße
    Thomas
     
  4. FSP

    FSP Grünschnabel

    Ich kapier's nicht! Wenn ich count benutze, zählt er immer alle Knoten im gesamten Dokument. Also wenn ich z.B. 5 von einander getrennte Aufzählungen in meiner XML-Datei habe, ist das Ergebnis von count 5. Er soll aber nur innerhalb einer Aufzählung zählen, ob es noch Unterhierarchien gibt.
    Also wenn meine XML-Datei z.B. so aussieht:

    <AUFZ>bla bla
    bla bla
    <AUFZ>bla bla
    </AUFZ>
    bla bla
    </AUFZ>
    bla bla
    bla bla
    <AUFZ>bla bla
    bla bla
    <AUFZ>bla bla
    </AUFZ>
    bla bla
    </AUFZ>
    bla bla

    ...dann soll der Zähler nicht die insgesamt 4 <AUFZ>-Knoten zählen, sondern nur innerhalb eines <AUFZ>-Knotens einen Zähler von 0 auf 1 stellen, wenn innerhalb dieses Knotens noch ein zweiter Knoten zweiter Hierarchie aufgeht.
    Mittlerweile habe ich zwar Beispiele für Hierarchienzähler gefunden, aber die funktionieren bei mir alle nicht, weil diese Beispiele dann doch immer geringfügig anders sind als ich es brauchen würde.
    Ich dreh noch durch. Das kann doch nicht sooo schwer sein!
    :mad::(
     
  5. FSP

    FSP Grünschnabel

    Mittlerweile konnte mir jemand mit dem "count" weiterhelfen und hat das Problem lösen können. Es muss so aussehen:

    <xsl:template match="/">
    <html>
    <body>
    <xsl:apply-templates/>
    </body>
    </html>
    </xsl:template>

    <xsl:template match="AUFZ">
    <div class="{concat('aufzaehlung',count(ancestor::AUFZ))}"><xsl:apply-templates/></div>
    </xsl:template>

    Das Ergebnis sieht so aus:
    <div class="aufzaehlung0">bla bla
    bla bla
    <div class="aufzaehlung1">bla bla
    </div>
    bla bla
    </div>

    Vielen Dank für Deinen Hilfe, ohne Deinen Anstoß mit dem "count" wäre ich wahrscheinlich nicht weitergekommen. :)