XML | XML-Schema | XPath | XSL-T | XSL-FO | XQuery | XProc | SVG |
XPath / XPath-Funktionen / Stringfunktionen / XPath: contains
![]() |
![]() |
➪ Die XPath-Funktion contains prüft, ob in einem String ein bestimmter Teilstring enthalten ist.
Auf dieser Seite:Siehe auch Stringanalyse mit count(tokenize).
contains kann Teil einer Fallunterscheidung (xsl:if, xsl:choose) sein, aber auch direkt als Prädikat verwendet werden, wodurch sich die relevante Position ändert.
<xsl:for-each select="//Mensch">
<xsl:if test="contains(vorname, 'ar')">
<m lfdnr="{position()}">
<xsl:value-of select="vorname"/>
</m>
</xsl:if>
</xsl:for-each>
Resultat:
<m lfdnr="10">Maria</m>
<m lfdnr="11">Mario</m>
Alternativer Aufruf mit abweichender Nummerierung:
<xsl:for-each select="//Mensch[contains(vorname, 'ar')]">
<m lfdnr="{position()}">
<xsl:value-of select="vorname"/>
</m>
</xsl:for-each>
Resultat:
<m lfdnr="1">Maria</m>
<m lfdnr="2">Mario</m>
Bei der Arbeit mit contains und anderen Funktionen ist es wichtig, im XPath-Statement einzelne Nodes zu adressieren. Würden Sie dagegen eine ganze Anzahl von Nodes ansprechen, etwa so:
<ergebnis>
<xsl:value-of
select="//*[contains(text(),'los')]"/>
</ergebnis>
so würde das Ergebnis je nach deklarierter XSL-Version unterschiedlich ausfallen.
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
</xsl:stylesheet>
In der version="1.0" geben unterschiedliche Prozessoren das erste gefundene Element aus, alle folgenden Elemente, die Sie mit [contains(text(),'los')] ebenfalls ansprechen, werden ignoriert (Informationsverlust!).
<ergebnis>Holzflos</ergebnis>
In der version="3.0" quittiert ein Prozessor denselben Aufruf dagegen mit einer Fehlermeldung:
Fehlerlevel: fatal
Beschreibung: XPTY0004: A sequence of more than one item
is not allowed as the first argument of contains() ("", "", ...)
Wollen Sie Case-insensitive nach einem Begriff suchen, zum Beispiel alle Textinhalte im Dokument, die die Zeichenkette "ne" enthalten, aber unabhängig von der Schreibweise (es sollen also auch "Ne", "NE" oder "nE" gefunden werden, so bietet sich die Arbeit mit lower-case an:
<xsl:template match="/">
<ergebnis>
<xsl:for-each
select="/*/descendant::text()
[contains(lower-case(.), 'ne')]">
<gefunden>
<xsl:value-of select="."/>
</gefunden>
</xsl:for-each>
</ergebnis>
</xsl:template>
Das Ergebnis dieses Aufrufs finden Sie hier:
<ergebnis>
<gefunden>Neustadt</gefunden>
<gefunden>Simone</gefunden>
<gefunden>Werner</gefunden>
<gefunden>Leinenlos</gefunden>
<gefunden>Liane</gefunden>
</ergebnis>
Eine Alternative, die dasselbe Ergebnis zutage fördert, ist die matches - Funktion, mit einem Flag für die Case-insensitive Prüfung "i".
<xsl:for-each
select="/*/descendant::text()
[matches(., 'ne', 'i')]">
<gefunden>
<xsl:value-of select="."/>
</gefunden>
</xsl:for-each>
Eine dritte Alternative, die ebenfalls dasselbe Ergebnis zutage fördert, ist die Kombination der contains-Funktion mit translate.
<xsl:for-each
select="/*/descendant::text()
[contains(translate(., 'NE', 'ne'), 'ne')]">
<gefunden>
<xsl:value-of select="."/>
</gefunden>
</xsl:for-each>
Je nach verwendetem Prozessor finden Sie eine vierte Alternative in der Arbeit mit einer Collation als drittem Parameter. Zum Thema Collations siehe meine Anmerkungen zum Thema XPath: array:sort.
<xsl:for-each
select="/*/descendant::text()
[contains(., 'ne',
(: Collation-Zeichenkette :))]">
<gefunden>
<xsl:value-of select="."/>
</gefunden>
</xsl:for-each>
fn:contains-token prüft, ob die gegebene Zeichenkette einem Token entspricht, ggf. unter den Regeln der Collation.
fn:contains-token('eins zwei drei ', 'eins')
ergibt true.
fn:contains-token(
'Weg Straße Pfad ',
'Strasse',
'http://www.w3.org/2013/collation/UCA?lang=de;strength=primary')
ergibt ebenfalls true.
fn:contains-token(
'Weg Straße Pfad ',
'Strasse')
ergibt dagegen false.
wg / 15. März 2019
Fragen? Anmerkungen? Tipps?
Bitte nehmen Sie Kontakt zu mir auf.
V.i.S.d.P.: Wilfried Grupe * Klus 6 * 37643 Negenborn
☎ 0151. 750 360 61 * eMail: info10@wilfried-grupe.de