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 Einzelbuchstaben 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 zusammensetzt.
- flags="m"
Schaltet auf »mehrzeilig« (multiline). In Multiline-Modus m werden Zeilenumbrüche durch innerhalb des Strings vorkommende Newlinezeichen #x0A erkannt. Ist das m-Flag nicht gesetzt, so gilt der Stringmodus (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 Metazeichen $ auf jedes Zeilenende (das Zeichen, das dem Zeilenumbruchzeichen unmittelbar vorangeht).
- flags="i"
Deaktiviert die Unterscheidung zwischen Groß- und Kleinschreibung (case insensitive). Ist dieses Flag nicht gesetzt, so wird die Gleichheit zweier Zeichen nur erkannt, wenn ihre Unicode-Codepoints übereinstimmen (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-Zeichen 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 Zeichen 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«) | Quantifizierer; |
* (»gierig«) | Quantifizierer; |
? (»gierig«) | Quantifizierer; |
{n} | numerischer Quantifizierer; |
{n,} | numerischer Quantifizierer; |
{n, m} | numerischer Quantifizierer; |
( ) | 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 Quantifizierern {n, m} betrifft. Da das regex-Attribut die Verwendung eines Attributwert-Templates zulässt, müssen geschweifte Klammern, wenn sie literal verwendet 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 Element der Sequenz dem Vergleichsmuster, das zweite ist ein »non-matching«-Substring und so fort.
Entspricht der vollständige getestete String dem Vergleichsmuster oder ist dieses 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 Ausgabesequenz gebildet wird und deshalb weder die Instruktion xsl:matching-substring 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 Zeilenumbruch –, 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 weitergegeben, 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 parametrierbar. 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 werden. 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