XPath 3.0, XPath 2.0, XPath 1.0 / XPath Funktionen / Stringfunktionen / XPath: tokenize

XPath: tokenize

XPath: tokenize

➪ Die XPath-Funktion "tokenize" konvertiert einen token-String in eine Sequenz.

Die "tokenize"-Funktion ist im Grunde das Gegenstück zu . Während "string-join" in der Lage ist, eine Sequence mit mehreren Items in einen Einzelstring zu konvertieren, wobei auch Trennzeichen eingefügt werden können (im Beispiel: ";"), kann "tokenize" einen derartigen unter Zuhilfenahme des Trennzeichens wieder in eine Sequence konvertieren.

Um das zu verdeutlichen, generieren wir zunächst eine Sequence aus den Werten 'Meier', 'Schulze', 'Müller', 'Schmidt' sowie den Zahlen 1 bis 10.


<xsl:variable name="v1" as="xs:string+">
  <xsl:for-each 
       select="('Meier', 
                'Schulze', 
                'Müller', 
                'Schmidt', 
                1 to 10)">
    <xsl:value-of select="."/>
  </xsl:for-each>
</xsl:variable>

Im nächsten Schritt konvertieren wir die Sequence in einen String mit dem Trennzeichen ";".


<xsl:variable name="v2" as="xs:string">
    <xsl:value-of select="string-join($v1, ';')"/>
</xsl:variable>

Denselben Effekt erreichen wir übrigens auch mit dem separator-Attribut von xsl:value-of:


<xsl:value-of 
     select="'Meier', 
             'Schulze', 
             'Müller', 
             'Schmidt', 
             1 to 10" 
     separator=";"/>

Zur Kontrolle können wir uns den generierten String anzeigen lassen:


<xsl:value-of select="$v2"/>

Hier ist also der String:


Meier;Schulze;Müller;Schmidt;1;2;3;4;5;6;7;8;9;10

Nun kommt "tokenize" ins Spiel, das den String in eine Itemlist aufsplittet:


<xsl:for-each 
     select="tokenize(xs:string($v2), ';')">
  <item>
    <xsl:value-of select="."/>
  </item>      
</xsl:for-each>

Resultat:


<item>Meier</item>
<item>Schulze</item>
<item>Müller</item>
<item>Schmidt</item>
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
<item>5</item>
<item>6</item>
<item>7</item>
<item>8</item>
<item>9</item>
<item>10</item>

Flags

Wie wollen wir jedoch verfahren, wenn die Zeichentrenner kein Semikolon darstellen, sondern aus Zeichen bestehen, die in Ausdrücken eine besondere Bedeutung haben, etwa "." oder "\"?


Meier.Schulze.Müller.Schmidt.1.2.3.4.5.6.7.8.9.10
Meier\Schulze\Müller\Schmidt\1\2\3\4\5\6\7\8\9\10

Da auch die tokenize-Funktion mit regulären Ausdrücken arbeitet, benötigen wir den Einsatz eines speziellen Flags "q", das dafür dorgt, daß Spezialzeichen in den regulären Ausdrücken als normale Zeichen betrachtet werden. Allgemeines zum Thema Flags finden wir unter .


<xsl:for-each 
     select="tokenize('Meier\Schulze\Müller\Schmidt', 
                      '\', 
                      'q')">
    <item>
        <xsl:value-of select="."/>
    </item>
</xsl:for-each>

Type-casting

Interessant ist auch die Variante, die einzelnen Items der generierten Sequence auf bestimmte Eigenschaften hin zu überprüfen, etwa, ob sie sich als "xs:integer" casten lassen. Damit fallen die Werte 'Meier', 'Schulze', 'Müller', 'Schmidt' aus der Sequence heraus, übrig bleiben die Integerwerte.


<xsl:for-each 
   select="tokenize(xs:string($v2), ';')
           [. castable as xs:integer]">
  <item>
    <xsl:value-of select="."/>
  </item>      
</xsl:for-each>

Resultat:


<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
<item>5</item>
<item>6</item>
<item>7</item>
<item>8</item>
<item>9</item>
<item>10</item>

Sonderzeichen

Ein "xs:token" ist ein String ohne Carriage-Return (#xD), ohne Line-Feed (#xA), ohne Tabulator (#x9), ohne führende oder schließende Leerzeichen (#x20); auch darf es nicht zwei oder mehrere Leerzeichen in Folge haben. Ein kann jedoch auch jene Sonderzeichen beinhalten.


<xsl:variable 
     name="vstring" 
     as="xs:string"> ab;cde&#xA;fg  h;&#x9;i&#x9;jk </xsl:variable>
     <erg3>
        <xsl:for-each 
          select="tokenize($vstring, ';')">
          <item>
            <xsl:value-of select="."/>
          </item>   
        </xsl:for-each>
     </erg3>

Nun könnten wir erwarten, daß die tokenize-Funktion sich weigert, einen solchen String abzuarbeiten. Fehlanzeige:


   <erg3>
      <item>   ab</item>
      <item>cde
fg  h</item>
      <item>	i	jk    </item>
   </erg3>

Erst die kombinierte Anwendung von löscht die unerwünschten Sonderzeichen, so daß die tokenize-Funktion zu einem anderen Resultat kommt.


<erg4>
  <xsl:for-each 
    select="tokenize(normalize-space($vstring), ';')">
    <item>
      <xsl:value-of select="."/>
    </item>   
  </xsl:for-each>
</erg4>

Das Ergebnis:


<erg4>
   <item>ab</item>
   <item>cde fg h</item>
   <item> i jk</item>
</erg4>

wg / 4. März 2018



Fragen? Anmerkungen? Tips?

Bitte nehmen Sie Kontakt zu mir auf:

Vorname
Nachname
Mailadresse







Vielen Dank für Ihr Interesse an meiner Arbeit.


V.i.S.d.P.: Wilfried Grupe * Klus 6 * 37643 Negenborn

☎ 0151. 750 360 61 * eMail: info10@wilfried-grupe.de

www.wilfried-grupe.de/tokenize.html