xsl:analyze-string

(Auszug aus "XSLT 2.0 & XPath 2.0" von Frank Bongers, Kapitel 6.)

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

 

Mit Hilfe der in XSLT 2.0 hinzugekommenen Instruktion xsl:analyze-string ist es möglich, Zeichenketten des Quelldokuments zu analysieren. Hierbei werden reguläre Ausdrücke verwendet.

Klassifizierung Instruktion
Funktionsgruppe Testen von Stringwerten
Einführung XSLT 2.0

Position im Stylesheet und erlaubte Inhalte:

Die Instruktion xsl:analyze-string tritt innerhalb von Template-Körpern auf.

Sie enthält – in dieser Reihenfolge – je kein oder ein Element xsl:matching-substring und xsl:non-matching-substring. Eine von beiden Sub-Instruktionen muss jedoch enthalten sein; d.h. entfällt die eine, so ist die jeweils andere obligatorisch. Darüber hinaus darf in der Instruktion eine beliebige Anzahl von xsl:fallback-Elementen stehen. (Anmerkung: Eine Fallback-Instruktion wird an dieser Stelle durch einen XSLT 2.0-konformen Prozessor ignoriert, kann aber für einen XSLT 1.0-fähigen Prozessor im vorwärtskompatiblen Modus relevant sein.)

Attribute:

Erlaubt sind alle Standardattribute. Darüberhinaus besitzt xsl:analyze-string drei elementspezifische Attribute; die obligatorischen Attribute select und regex sowie ein optionales Attribut flags.

flags

Wert

flag-String (auch als AVT)

Verwendung

Optional

Einführung

XSLT 2.0

Mittels der optional zu setzenden Flags kann die Wirkung des regulären Ausdrucks bestimmt werden. Die Flags sind an die Konventionen von Perl angelehnt. Als Flags sind Strings aus den Einzelbuch­sta­ben m, i, s, x oder sinnvolle Kombinationen aus diesen erlaubt.

Der Wert des flags-Attributs kann dynamisch durch ein Attributwert-Template ermittelt werden. Es gilt als Fehler, wenn der sich ergebende Wert sich nicht aus einem oder mehreren der für Flags vorgesehenen Buchstaben zusammen­setzt.

  • flags="m"
    Schaltet auf »mehrzeilig« (multiline). In Multiline-Modus m werden Zeilenumbrüche durch innerhalb des Strings vorkommende Newli­nezeichen #x0A erkannt. Ist das m-Flag nicht gesetzt, so gilt der Stringmo­dus (Anmerkung: Dieser entspricht jedoch nicht dem »dot-all«-Modus bei gesetztem Flag »s«!), d.h., Zeilenumbrüche innerhalb des Strings werden nicht besonders beachtet, sondern lediglich Anfang (Metazeichen ^) und Ende (Metazeichen $) des gesamten Strings als Begrenzungen erkannt (Default). Bei gesetztem m-Flag passt das Metazeichen ^ zusätzlich auf jeden Zeilenbeginn (d.h. auf das Zeichen, das unmittelbar dem Zeilenumbruchzeichen folgt) und das Meta­zeichen $ auf jedes Zeilenende (das Zeichen, das dem Zeilenumbruchzeichen unmittelbar vorangeht).
  • flags="i"
    Deaktiviert die Unterscheidung zwischen Groß- und Klein­schreibung (case insensitive). Ist dieses Flag nicht gesetzt, so wird die Gleich­heit zweier Zeichen nur erkannt, wenn ihre Unicode-Codepoints überein­stimmen (Default). Bei gesetztem Flag gelten zwei Zeichen als gleich, wenn gemäß der Unicode Case Mappings ein canonical caseless match vorliegt. (Anmerkung: Dies wird durch »case-folding« erreicht. Ein Beispiel sind die griechischen Zeichen Σ und ς, die in diesem Fall als »match« angesehen werden.)
  • flags="x"
    Deaktiviert die Beachtung von Whitespace-Zeichen innerhalb des regulären Ausdrucks. Ist das Flag nicht gesetzt, werden Whitespace-Zei­chen als Teil des Ausdrucks betrachtet und für den Match verwendet (Default). Das gesetzte Flag ermöglicht es, längere reguläre Ausdrücke durch den Einsatz von Zeilenumbrüchen übersichtlicher zu gestalten.
  • flags="s"
    Schaltet in den sogenannten »dot-all«-Modus um (dies entspricht dem »single-line«-Modus von Perl). Beeinflusst wird das Verhalten des Metazeichens ».« (dot). Ohne gesetztes s-Flag trifft dieses Metazeichen auf alle Zeichen (auch Whitespace!) zu, außer auf das Zeilenumbruchzeichen #x0A (Default). Bei gesetztem Flag hingegen steht der Punkt für alle Zeichen inklusive des Zeilenumbruchs.

Problematik – Erkennen von Zeilenumbruch als Wortgrenze:
Bildet ein einzelnes Zeilenumbruchzeichen die Grenze zwischen zwei Worten (also ohne weiteres dazwischen liegendes Leerzeichen!), so wird dies nur im »dot-all«-Modus als zwischen den Worten liegendes Zei­chen erkannt.

regex

Wert

regular expression (auch als AVT)

Verwendung

Obligatorisch

Einführung

XSLT 2.0

Das Attribut regex enthält einen regulären Ausdruck (regular expression), der zur Prüfung des Strings herangezogen wird. Der reguläre Ausdruck kann als Attributwert-Template eingefügt werden. Es ist ein Fehler, wenn der sich dabei ergebende reguläre Ausdruck auf den leeren String passt.

select

Wert

xpath-expression

Verwendung

Obligatorisch

Einführung

XSLT 2.0

Das Attribut select nimmt einen XPath-Ausdruck entgegen, der den zu prüfenden String auswählt.

Verwendung:

Die Instruktion xsl:analyze-string nimmt einen Eingabestring entgegen, der dem Stringwert des XPath-Ausdrucks im select-Attribut entspricht. Das Attribut regex enthält ein Vergleichsmuster in Form eines regulären Ausdrucks. Der Eingabestring wird an den Positionen gefundener Übereinstimmungen mit dem Vergleichsmuster in eine Sequenz aus Teilstrings vom Typ xs:string zerlegt und in einer Ausgabesequenz angeordnet.

Passt der reguläre Ausdruck an mehreren Stellen des untersuchten Strings, so wird der erste Match ausgewählt. Die Untersuchung wird ab einschließlich dem ersten, auf den gefundenen Teilstring folgenden Zeichen fortgesetzt.

Der reguläre Ausdruck wird gemäß der von Perl bekannten Syntax gebildet. Es gelten die üblichen Metazeichen, wie sie in der folgenden Tabelle aufgelistet sind.

Metazeichen Beschreibung

.

Der Punkt steht für jedes beliebige Zeichen, inklusive des Zeilenumbruchs (#x0A), solange das m-Flag nicht explizit angegeben wurde.

^

Der (vorangestellte) Zirkumflex steht für den Anfang der Zeichenkette bzw. den Zeilenanfang bei gesetztem Flag m (dient auch als Negation in Zeichenlisten).

$

Das (nachgestellte) Dollarzeichen steht für das Ende der Zeichenkette bzw. das Zeilenende bei gesetzem Flag m.

|

Das Pipe-Symbol wird im Sinne von »oder« verwendet, um zwischen Zeichen oder Gruppen zu wählen.

+ (»gierig«)
+? (»nicht gierig«)

Quantifizierer;
vorangehendes Zeichen kommt ein- oder mehrmals vor;
nachgestelltes Fragezeichen kennzeichnet die »nicht-gierige« Version des Quantifizierers.

* (»gierig«)
*? (»nicht gierig«)

Quantifizierer;
vorangehendes Zeichen kommt kein- oder mehrmals vor; nachgestelltes Fragezeichen kennzeichnet die »nicht-gierige« Version des Quantifizierers.

? (»gierig«)
?? (»nicht gierig«)

Quantifizierer;
vorangehendes Zeichen kommt kein- oder einmal vor;
nachgestelltes Fragezeichen kennzeichnet die »nicht-gierige« Version des Quantifizierers.

{n}

numerischer Quantifizierer;
vorangehendes Zeichen kommt genau n-mal vor.

{n,}

numerischer Quantifizierer;
vorangehendes Zeichen kommt mindestens n-mal vor.

{n, m}

numerischer Quantifizierer;
vorangehendes Zeichen kommt mindestens n-mal, aber höchstens m-mal vor.

( )

Runde Klammern dienen zur Bildung von Untergruppen für Backreferences innerhalb des Patterns (auf die mit der Funktion regex-group() zugegriffen werden kann).

[]

Eckige Klammern dienen zur Angabe von Zeichenlisten bzw. -klassen.

Tabellle: Metazeichen in XPath-RegEx-Ausdrücken. 

Vorsicht Falle – RegEx im Attributwert-Template:

Ein wichtiger Umstand muss beim Schreiben von regulären Ausdrücken in diesem Kontext berücksichtigt werden, der die Verwendung von numerischen Quantifizie­rern {n, m} betrifft. Da das regex-Attribut die Verwendung eines Attribut­wert-Templates zulässt, müssen geschweifte Klammern, wenn sie literal ver­wendet werden, verdoppelt werden – auch innerhalb des enthaltenen regulären Ausdrucks.

Folgender reguläre Ausdruck, der eine Gruppe von 1 bis maximal 3 beliebigen Zeichen (der Punkt '.', gefolgt von einem numerischem Quantifizierer in geschweiften Klammern) und einem Leerzeichen beschreibt

.{1, 3}\s

muss daher innerhalb des regex-Attributs mit verdoppelten geschweiften Klammern geschrieben werden:

regex=".{{1, 3}}\s" 

Die Sequenzbildung:

Wird am Beginn des Strings keine Übereinstimmung mit dem Suchmuster gefunden, so enthält der erste Teilstring alle Zeichen bis zur ersten Übereinstimmung, schließt diese selbst aber nicht mit ein. Der zweite Teilstring entspricht dem Suchmuster selbst. Ein dritter Teilstring bestünde wieder aus einem »non-matching«-Abschnitt, der das Suchmuster nicht enthält etc.

Beginnt der Eingabestring mit dem Suchmuster, so entspricht das erste Ele­ment der Sequenz dem Vergleichsmuster, das zweite ist ein »non-matching«-Substring und so fort.

Entspricht der vollständige getestete String dem Vergleichsmuster oder ist die­ses in ihm nicht enthalten, so wird genau ein Teilstring gebildet, der aus dem vollständigen Inputstring besteht. Dieser stellt dann entweder einen Match dar oder nicht.

In keinem Fall darf ein Teilstring gebildet werden, der aus dem leeren String besteht. Dies hat zur Folge, dass für einen leeren Inputstring keine Ausgabese­quenz gebildet wird und deshalb weder die Instruktion xsl:matching-subst­ring noch xsl:non-matching-substring in Kraft treten wird. 

Die Verarbeitung der Sequenz:

Im Normalfall einer nicht leeren Sequenz werden die Teilstrings der Reihe nach an die Instruktionen xsl:matching-substring und xsl:non-matching-substring weitergegeben und deren jeweilige Sequenzkonstruktoren bzw. Templateblöcke werden ausgeführt. Fehlt eine der beiden Instruktionen, so wird dieser Fall jeweils behandelt, als ob das fehlende Element mit leerem Template-Body vorhanden wäre. Fehlen dageben beide Instruktionen, so ist dies ein statischer Fehler (ERR XTSE1130).

Bei der Auswertung der Sequenz wird der jeweils verarbeitete Teilstring zum Kontextitem und seine Position in der Sequenz die Kontextposition. Die Zahl der Teilstrings in der Sequenz wird als Kontextgröße bezeichnet.

Beispiele:

Beispiel 1 – Zeilenumbrüche \n durch HTML-<br> ersetzen:

<xsl:analyze-string select="abschnitt" regex="\n">
  <xsl:matching-substring>
    <br/>
  </xsl:matching-substring>
  <xsl:non-matching-substring>
    <xsl:value-of select="."/>
  </xsl:non-matching-substring>
</xsl:analyze-string>

Der reguläre Ausdruck "\n" passt auf den Zeilenumbruchbefehl. Analysiert wird der Stringwert eines <abschnitt>-Containers. Die xsl:non-matching-substring-Instruktion nimmt all jene Teile des Eingabestrings entgegen, auf die der reguläre Ausdruck nicht passt – also alle Zeichen außer dem Zeilenum­bruch –, und gibt sie ins Ergebnisdokument aus. Wird bei der Analyse ein Umbruchzeichen gefunden, tritt die Instruktion xsl:matching-substring in Kraft und schreibt einen HTML-Break. Der matching-Substring, also das ursprünglich im Eingabestring enthaltene Umbruchzeichen, wird nicht weiter­gegeben, sondern verworfen.

Beispiel 2 – Zeichenkette in Fließtext ersetzen:

Quelldokument:

<?xml version="1.0" encoding="ISO-8859-1"?>
<beispieltext>Jazzbassisten gibt es wie Sand am Meer. Jazzbassisten, die ehemals Gitarristen waren, und deren Spiel dadurch hörbar geprägt ist, sind schon seltener.</beispieltext>

In diesem Text soll die Zeichenkette »Jazzbassist« jeweils durch »Violinist« ersetzt werden.

Stylesheet:

<xsl:template match="/">
  <ausgabe>
    <xsl:call-template name="substring-ersetzen">
      <xsl:with-param name="suchstring" select="'Jazzbassist'"/>
      <xsl:with-param name="ersetzungsstring" select="'Violinist'"/>
    </xsl:call-template>
  </ausgabe>
</xsl:template>
<xsl:template name="substring-ersetzen">
  <xsl:param name="suchstring"/>
  <xsl:param name="ersetzungsstring"/>
  <xsl:analyze-string regex="{$suchstring}" select="beispieltext">
    <xsl:matching-substring>
      <xsl:value-of select="$ersetzungsstring"/>
    </xsl:matching-substring>
    <xsl:non-matching-substring>
      <xsl:value-of select="."/>
    </xsl:non-matching-substring>
  </xsl:analyze-string>
</xsl:template>

Die Verwendung eines benannten Templates ist bei diesem einfachen Beispiel nicht unbedingt erforderlich, macht aber die Stringersetzung von außen para­metrierbar. Im Prinzip könnte dies so ähnlich auch in einer Stylesheetfunktion umgesetzt werden.

Ergebnis:

<?xml version="1.0" encoding="UTF-8"?>
<ausgabe>Violinisten gibt es wie Sand am Meer. Violinisten, die ehemals Gitarristen waren, und deren Spiel dadurch hörbar geprägt ist, sind schon seltener.</ausgabe>

In einem Text soll eine konkrete Zeichenkette durch eine andere ersetzt wer­den. Dies ist hier mittels xsl:analyse-string gelöst, wobei die Instruktion in ein benanntes Template ausgelagert wurde. Such- und Ersetzungszeichenkette werden durch Parameter übergeben. Zu beachten ist das regex-Attribut, das den übergebenen Parameter mittels eines Attributwert-Templates erhält (die geschweiften Klammern sind erforderlich, damit der Parameter ausgewertet werden kann).

Weitere Beispiele:
Weitere Beispiele, auch zur Funktion regex-group(), befinden sich bei den Erläuterungen zu xsl:matching-substring sowie xsl:non-matching-substring.

Elementdefinition:

XSLT 1.0:

Element in XSLT 1.0 nicht verfügbar.

XSLT 2.0:

<!-- Category: instruction -->
<xsl:analyze-string
     select = expression
     regex = { string }
     flags? = { string } >

  <!-- Content: (xsl:matching-substring?, xsl:non-matching-substring?, xsl:fallback*) -->
</xsl:analyze-string>
Tipp der data2type-Redaktion:
Zum Thema XSLT bieten wir auch folgende Schulungen zur Vertiefung und professionellen Fortbildung an:

Copyright © Galileo Press, Bonn 2008
Für Ihren privaten Gebrauch dürfen Sie die Online-Version ausdrucken.
Ansonsten unterliegt dieses Kapitel aus dem Buch "XSLT 2.0 & XPath 2.0 ― Das umfassende Handbuch" denselben Bestimmungen wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Galileo Press, Rheinwerkallee 4, 53227 Bonn