whine: String zerlegen

Hallo zusammen!

Ich habe in einer XML folgendes

<zf>wortabc#wortdef#wortganzdolllang#wort1#wort3345#wort777...<zf>

Nun möchte ich gern mit xslt eine Ausgabe erzeugen, welche mit immer ein durch die # getrenntes Paar untereinander ausgibt (oder erstmal in eine Variable schreibt). Im o.g. Bsp. also

wortabc#wortdef#
wortganzdolllang#wort1#
wort3345#wort777
...

Ich habe schon mit substring-before und substring-after rumgespielt, aber so richtig bin ich auf keinen grünen Zweig gekommen.
Hat jemand eine Idee?

whine

  1. Hallo,

    Ich habe schon mit substring-before und substring-after rumgespielt, aber so richtig bin ich auf keinen grünen Zweig gekommen.

    Wenn du das Ganze jetzt noch rekursiv machst und immer den Reststring als Parameter übergibst, dann wird's ein grüner Zweig.

    Unter rekursiv versteht man ein Template, das sich immer wieder selbst aufruft, bis eine bestimmte Bedingung erfüllt ist. Einfach mal googeln.

    Bei jedem Aufruf machst Du dann 2 x substring-before und der Rest ist dann jeweils substring-after. Die Ergebnisse der substring-before-Methode kannst du dann nach eigenem Gutdünken verarbeiten, z.B. mit concat wieder zu dem Paar a la StringPart1#StringPart2# zusammenfügen.

    Viele Grüße
    Siri

  2. Hallo

    Hat jemand eine Idee?

    Eine Idee hab ich. Gibt aber vll. noch einfachere.

    Mit Explode:
    http://www.php.net/manual/de/function.explode.php

    Anschließend jeweils 2 Arrays zusammenführen, das geht dann in einer Schleife. 0+1,2+3,4+5,6+7 usw. Dazwischen nicht die Raute vergessen, die entfällt beim aufteilen mit explode.

    lg,
    Roland

    1. Hallo,

      Hat jemand eine Idee?

      Eine Idee hab ich.

      Aber keine gute, weil es um XSL geht ;-)

      Viele Grüße
      Siri

  3. Hallo whine,

    Ich habe in einer XML folgendes

    <zf>wortabc#wortdef#wortganzdolllang#wort1#wort3345#wort777...<zf>

    Nun möchte ich gern mit xslt eine Ausgabe erzeugen, welche mit immer ein durch die # getrenntes Paar untereinander ausgibt (oder erstmal in eine Variable schreibt). Im o.g. Bsp. also

    wortabc#wortdef#
    wortganzdolllang#wort1#
    wort3345#wort777
    ...

    Ich habe schon mit substring-before und substring-after rumgespielt, aber so richtig bin ich auf keinen grünen Zweig gekommen.
    Hat jemand eine Idee?

    Für XSLT 2.0 (ansonsten, wie gesagt, rekursiv zerlegen):

    <xsl:variable name="tok" select="fn:tokenize(zf, '#')"/>  
      
    <xsl:for-each select="$tok">  
      <xsl:variable name="pos" select="fn:position()"/>  
      <xsl:if test="$pos mod 2 != 0">  
        <xsl:value-of select="fn:concat($tok[$pos], '#', $tok[$pos + 1], if($pos != fn:last() - 1) then '#&#xA;' else())"/>  
      </xsl:if>  
    </xsl:for-each>
    

    Erzeugt:
    wortabc#wortdef#
    wortganzdolllang#wort1#
    wort3345#wort777...

    Grüße,
    Thomas

  4. Hallo whine,

    das Problem kenne ich.
    Wenn du mit dem XSLT Processor 1.0 arbeitest gibt es keine andere Möglichkeiten soviel ich weiß.

    wortabc#wortdef#
    wortganzdolllang#wort1#
    wort3345#wort777
    ...

    Ich habe schon mit substring-before und substring-after rumgespielt, aber so richtig bin ich auf keinen grünen Zweig gekommen.
    Hat jemand eine Idee?

      
    <!-- template aufruf -->  
    <xsl:call-template name="explode">  
     <xsl:with-param name="text" value="abc#123#xyz#890" />  
    </xsl:call-template>  
      
    <!-- haupt template -->  
    <xsl:template name="explode">  
    <xsl:param name="text" />  
    <xsl:if test="string-length($text) > 0">  
      <xsl:when test="string-length(substring-before($text, '#')) > 0">  
           <xsl:call-template name="output">  
              <xsl:with-param name="message">  
               <xsl:value-of select="substring-before($text, '#')" />  
              </xsl:with-param>  
           </xsl:call-template>  
      </xsl:when>  
      <xsl:otherwise>  
           <xsl:call-template name="output">  
              <xsl:with-param name="message">  
                <xsl:value-of select="$text" />  
              </xsl:with-param>  
           </xsl:call-template>  
      </xsl:otherwise>  
    </xsl:if>  
    </xsl:template>  
      
    <!-- ausgabe template -->  
    <xsl:template name="output">  
    <xsl:param name="message" />  
     <!-- ausgabe implementieren -->  
    </xsl:template>  
    
    

    Meine letzte XSL Aufabe sah vor in einem Kreditkarten Template des Payment Providers eine XML Variable auszulesen bzw. eins der Nodes mit folgendem Inhalt:

      
    <root>  
     <allowed>1,2,4,5</allowed>  
     ...  
    </root>  
    
    

    Ich musste also ählich wie Du an einem bestimmten Zeichen "splitten", in meinem Fall das Komma, bei dir die Raute. Den Code musste ich etwas abwandeln, sollte aber mit wenigen Anpassungen funktionieren.

    Schön ist das nicht, aber soviel ich googeln konnte gibt es erst ab XSLT 2.0 bessere Methoden zur Datenverarbeitung.

    1. Edit: add choose

      <!-- haupt template -->
      <xsl:template name="explode">
      <xsl:param name="text" />
      <xsl:if test="string-length($text) > 0">
      xsl:choose
         <xsl:when test="string-length(substring-before($text, '#')) > 0">
             <xsl:call-template name="output">
                <xsl:with-param name="message">
                 <xsl:value-of select="substring-before($text, '#')" />
                </xsl:with-param>
             </xsl:call-template>
         </xsl:when>
         xsl:otherwise
             <xsl:call-template name="output">
                <xsl:with-param name="message">
                  <xsl:value-of select="$text" />
                </xsl:with-param>
             </xsl:call-template>
        </xsl:otherwise>
      </xsl:choose>
      </xsl:if>
      </xsl:template>