PeterK: XSL - Split

Hallo.
Gibt es eine art Split / Explode-Funktion für xsl? Ich habe mal versucht selbst sowas zu schreiben, aber es ist am fehlen einer while-Schleife gescheitert. Vieleicht gehe ich das Problem auch falsch an, aber mir fehlt nix besseres ein. Also das xslt ließt ein menü rekursiv aus einem xml-file ein und gibt es aus. Das funktioniert auch schon ganz wunderbar. Allerdings soll nun nur ein bestimmter Teil des Menüs ausgegeben werden. Der Teil wird über einen Parameter, der dem Stylesheet übergeben wird definiert und zwar in form eines Strings (es können ja nur Strings als Parameter übergeben werden) in der Form "projekte.php.hp". Die Gegenstücke zu den Namne sind als Attributknoten in der Menü-Xml-Datei referenziert. Nun muss ich ja z.B. für das Element "Projekte" ob an der Tiefe 2 im Menüpfad auch "projekte" steht. Wenn ja -> Children abarbeiten, sonst nächstes Element. Dazu muss ich aber den Menüpfad irgendwie zerlegen und ganu dazu bräuchte ich sowas.

Thx, Peter

--

--
Wer Rechtschreibfehler findet darf sie behalten.
  1. Hallo,

    Gibt es eine art Split / Explode-Funktion für xsl?

    Nur bedingt: mit recursiven Templates.

    Allerdings soll nun nur ein bestimmter Teil des Menüs ausgegeben werden. Der Teil wird über einen Parameter, der dem Stylesheet übergeben wird definiert und zwar in form eines Strings [...]in der Form "projekte.php.hp". Die Gegenstücke zu den Namne sind als Attributknoten in der Menü-Xml-Datei referenziert. Nun muss ich ja z.B. für das Element "Projekte" ob an der Tiefe 2 im Menüpfad auch "projekte" steht. Wenn ja -> Children abarbeiten, sonst nächstes Element. Dazu muss ich aber den Menüpfad irgendwie zerlegen und ganu dazu bräuchte ich sowas.

    Ich verstehe nicht was du meinst.
    Du sagst: "Wer Rechtschreibfehler findet darf sie behalten", mach ich ja gerne. Würdest du trotzdem versuchen mir nochmal zu erklären, was du meinst? Vielleicht mit Code-Teilen?

    »»(es können ja nur Strings als Parameter übergeben werden)
    Nein, aber es dürfte hier egal sein.

    Grüße
    Thomas

    1. Also folgendes:

      Das xsl-Script wird von einem php-script aus aufgerufen. Es stellt soll eine Menü-Datei in ein Aufklappbares Menü verwandeln.

      Die Menü-XML ist folgendermaßenm aufgebaut:

      <menu>
       <item name="start" text="Startseite" link="internal://start" />
       <item name="ich" text="Ich">
        <item name="steckbrief" text="Steckbrief" link="internal://ich/steckbrief" />
        <item name="lebenslauf" text="Lebenslauf" link="internal://ich/lebenslauf" />
        <item name="kontakt" text="Kontakt" link="internal://ich/kontakt" />
       </item>
       <item name="projekte" text="Projekte">
        <item name="php" text="PHP">
         <item name="pxml" text="PXML" link="internal://projekte/php/pxml" />
         <item name="xmldoc" text="XMLDoc" link="internal://projekte/php/xmldoc" />
         <item name="xmlmenu" text="XMLMenu" link="internal://projekte/php/xmlmenu" />
        </item>
        <item name="vb" text="VB">
         <item name="sbiii" text="SB III" link="internal://projekte/vb/sbiii" />
        </item>
        <item name="bbs4u" text="BackBone-Systems 4u">
         <item name="forum" text="Das Forum" link="http://forum.backbone-systems4u.de" extern="true" />
         <item name="chat" text="Der Chat" link="http://chat.backbone-systems4u.de" extern="true" />
        </item>
       </item>
       <item name="impressum" text="Impressum" link="internal://impressum" />
      </menu>

      Das xsl-Script reagiert nun auf den menu-Eintrag und ruft dann per xsl:call-template ein Template auf, dass sich dannentsprechend den Sub-Items selbst wieder aufruft. (Rekursion). Das funktioniert auch wunderbar. Als ergebnis erhalte ich in etwa folgendes:

      Start
      Ich
        Steckbrief
        Lebenslauf
        Kontakt
      Projekte
        PHP
          PXML
          XMLDoc
          XMLMenu
        VB
          SB III
        BackBone-Systems 4u
          Das Forum
          Der Chat
      Impressum

      Nun soll aber über eine Get-Variable, die ich dem Php-Script übergeben die Ausgabe geregelt werden. Der Wert der GET-Variable wird dem XSLT-Prozessor als Parameter übergeben. Also wenn die Variable "ich" enthält, dann soll die ausgabe

      Start
      Ich
        Steckbrief
        Lebenslauf
        Kontakt
      Projekte
      Impressum

      lauten. Wenn die Variable "projekte.vb" lauten, dann wird dass ausgegebn:

      Start
      Ich
      Projekte
        PHP
        VB
          SB III
      Impressum

      Um das zu erreichen muss ich den Pfad, also den Inhalt der Variable an den punkten trennen und dazu benötige ich eine Split-Funktion.

      Was MudGuard gesagt hat, mit den Mehreren Variablen, geht nciht, da der Pfad ja eine Beliebeige Tiefe haben kann, ich also nicht weiß wieviele Parameter ich brauche...

      Hoff ich konnte dass jetzt etwas verständlicher machen.
      Peter

      1. Hi,

        Es stellt soll eine Menü-Datei in ein Aufklappbares Menü verwandeln.
        Was MudGuard gesagt hat, mit den Mehreren Variablen, geht nciht, da der Pfad ja eine Beliebeige Tiefe haben kann, ich also nicht weiß wieviele Parameter ich brauche...

        Meinst Du, daß ein Klappmenü mit mehr als 5 Ebenen dem User noch zuzumuten ist?

        Ich halte eher 4 Ebenen schon für grenzwertig.

        Aber egal, wo man die Grenze zieht, es wird immer eine endliche Anzahl von Ebenen sein, also kann man diese auch im XSLT vorgeben.

        cu,
        Andreas

        --
        Der Optimist: Das Glas  ist halbvoll.  - Der Pessimist: Das Glas ist halbleer. - Der Ingenieur: Das Glas ist doppelt so groß wie nötig.
        http://mud-guard.de/? http://www.andreas-waechter.de/ http://www.helpers.de/
        1. Mag sein dass 4 Ebenen schon langen, aber was ist, wenn ich z.B. unterhalb des SB III-Projektes die einzelnen Module aufführe und dann die Dokumentationen zu den einzelnen Funktionen? Tatsache ist, dass es nicht sauber ist, eine beschränkung auf z.B. 9 Ebenen einzuführen. Ich werde es mal versuchen, aber mir wäre es anders lieber...

          Peter

          1. Ich habe eine Lösung gefunden:

            <xsl:template name="str:split">
             <xsl:param name="string" select="''" />
             <xsl:param name="pattern" select="' '" />
             xsl:choose
              <xsl:when test="contains($string, $pattern)">
               <xsl:if test="not(starts-with($string, $pattern))">
                <xsl:call-template name="str:split">
                 <xsl:with-param name="string" select="substring-before($string, $pattern)" />
                 <xsl:with-param name="pattern" select="$pattern" />
                </xsl:call-template>
               </xsl:if>
               <xsl:call-template name="str:split">
                <xsl:with-param name="string" select="substring-after($string, $pattern)" />
                <xsl:with-param name="pattern" select="$pattern" />
               </xsl:call-template>
              </xsl:when>
              xsl:otherwise
               <token><xsl:value-of select="$string" /></token>
              </xsl:otherwise>
             </xsl:choose>
            </xsl:template>

            Diese Funktion teilt einen String anhand eines Trennzeichens in eine Liste von token-Elements die dann per Index-Zahlen angesprochen werden können.

            Peter

            1. Hallo,

              Ich habe eine Lösung gefunden:

              Du meinst du hast den Template vom Kipp Howard gefunden. ;-)
              http://www.exslt.org/str/functions/split/str.split.template.xsl

              Du muss aber auch noch dazusagen, dass man dabei (fairer Weise!!) den Namensraum "str" definieren muss: xmlns:str="http://exslt.org/strings

              Den Template muss du noch aber mächtig anpassen, denn er generiert lediglich eine Liste von Elementen, was in deinem Fall nicht wirklich das sein soll was du dir gewünscht hast.

              Wie auch immer, wenn es dir passt ist ja alles ok ;-)

              Grüße
              Thomas

              1. Hi

                1.Habe ich den Namesraum einfach entfernt und das Template "splitstring" genannt.
                2. Ist es genau das was ich siche. Auf die einzelnen elemente kann ich per $arr/token[n] zugreifen - mehr brauch ich doch garnicht.

                Auf alle fälle tut es seinen Zweck.

                Peter

                1. Hallo,

                  1.Habe ich den Namesraum einfach entfernt und das Template "splitstring" genannt.

                  Dass das geht weisst ich, deshalb eigentlich mein hinweis auf "fairer Weise".

                  1. Ist es genau das was ich siche. Auf die einzelnen elemente kann ich per $arr/token[n] zugreifen - mehr brauch ich doch garnicht.

                  Ah, du wolltest also gar keine HTML-Ausgabge.

                  Auf alle fälle tut es seinen Zweck.

                  Darum gings ja ;-)

                  Grüße
                  Thomas

  2. Hi,

    Der Teil wird über einen Parameter, der dem Stylesheet übergeben wird definiert und zwar in form eines Strings (es können ja nur Strings als Parameter übergeben werden) in der Form "projekte.php.hp".

    Es ist aber möglich, mehr als einen Parameter zu übergeben - du könntest also statt eines Strings mehrere übergeben, z.B. als
    level0=projekte, level1=php, level2=hp

    Ansonsten rumpfriemeln mit substring und Co...

    cu,
    Andreas

    --
    Der Optimist: Das Glas  ist halbvoll.  - Der Pessimist: Das Glas ist halbleer. - Der Ingenieur: Das Glas ist doppelt so groß wie nötig.
    http://mud-guard.de/? http://www.andreas-waechter.de/ http://www.helpers.de/