Home
Über mich
Blog
Veröffentlichungen
IT-Trainings
Impressum


XPath: compare

Zusammenfassung:

Die "compare"-Funktion vergleicht zwei Stringparameter miteinander.

XPath: compare

Sind beide Strings gleich, ist das Ergebnis "0" (etwa bei compare('abc', 'abc')). Sind die Parameter nicht gleich, ist das Resultat entweder 1 oder -1, je nachdem, ob die beiden Vergleichsparameter kleiner oder größer sind. Um das zu demonstrieren, nehmen wir uns die "string-to-codepoints" zu Hilfe.

Die Variable v1 erhält den Wert "Hugo".

<xsl:variable name="v1" select="string(//Ort[1]/Mensch[1]/vorname)"/>

Die Variable v2 erhält den Wert "Helmut".

<xsl:variable name="v2" select="string(//Ort[1]/Mensch[2]/vorname)"/>

Zu Demonstrationszwecken vergleichen wir die Variable v1 mit v1:

<v1v1 v1="{$v1}">
    <xsl:value-of select="compare($v1, $v1)"/>
</v1v1>

das Ergebnis ist 0.

<v1v1 v1="Hugo">0</v1v1>

Vergleichen wir v1 (Hugo) dagegen mit dessen Konvertierung in Kleinbuchstaben (lower-case: hugo), ...

<v1v1lc 
  v1="{$v1}"
  v1cp="{string-to-codepoints($v1)}"
  v1lc="{lower-case($v1)}"
  v1lccp="{string-to-codepoints(lower-case($v1))}">
    <xsl:value-of select="compare($v1, lower-case($v1))"/>
</v1v1lc>

... so ist das Ergebnis -1.

<v1v1lc v1="Hugo"
 v1cp="72 117 103 111"
 v1lc="hugo"
 v1lccp="104 117 103 111">-1</v1v1lc>

Ein Vergleich von Hugo und Helmut dagegen ...

<v1v2 
  v1="{$v1}" 
  v1cp="{string-to-codepoints($v1)}" 
  v2="{$v2}" 
  v2cp="{string-to-codepoints($v2)}">
    <xsl:value-of select="compare($v1, $v2)"/>
</v1v2>

ergibt das Resultat 1.

<v1v2 v1="Hugo"
 v1cp="72 117 103 111"
 v2="Helmut"
 v2cp="72 101 108 109 117 116">1</v1v2>

Ein Vergleich von Helmut mit Hugo ergibt indes ...

<v2v1 
  v1="{$v1}" 
  v1cp="{string-to-codepoints($v1)}" 
  v2="{$v2}" 
  v2cp="{string-to-codepoints($v2)}">
    <xsl:value-of select="compare($v2, $v1)"/>
</v2v1>

... das Resultat -1.

<v2v1 v1="Hugo"
 v1cp="72 117 103 111"
 v2="Helmut"
 v2cp="72 101 108 109 117 116">-1</v2v1>

Das Ergebnis dieser Aufrufe sehen wir hier.

compare('Hugo', 'Hugo') 0
compare('Hugo', 'hugo') -1
compare('Hugo', 'Helmut') 1
compare('Helmut', 'Hugo') -1

Hier bleibt noch anzumerken, daß Stringvergleiche häufig im Rahmen von Fallunterscheidungen (xsl:if, xsl:choose) anzutreffen sind, dann oft ohne ausdrücklichen Aufruf der "compare"-Funktion.

<xsl:if test="$v1 != $v2">
      Beide Werte sind ungleich.
</xsl:if>

Ein Sonderfall ist auch hier der Vergleich von leeren Strings mit leeren Sequences. In diesem Fall gibt die "compare"-Funktion keinen Wert zurück. Erst ein explizites Casting der Parameter als String bzw. xs:string ergibt das Resultat "0".

<xsl:variable name="vleererString" 
              select="translate($v2, 'Helmut', '')"/>

Die translate-Funktion sorgt bei der oben beschriebenen Anwendung dafür, daß sämtliche Zeichen "Helmut" aus dem Input-Wert "Helmut" gelöscht werden; es handelt sich daher um einen leeren String.

<xsl:variable name="vleereSequence" 
              select="//Ort[1]/Mensch[1]/hobby"/>

Die Variable vleereSequence dagegen bezieht sich auf ein Element, das es im XML Input gar nicht gibt, die Sequence ist also leer.

<vergleich_leerstring_leereSequence 
     vleererString="{$vleererString}" 
     vleereSequence="{$vleereSequence}">
        <xsl:value-of 
             select="compare($vleereSequence, $vleererString)"/>
</vergleich_leerstring_leereSequence>

Ein Vergleich der leeren Sequence mit einem leeren String ergibt grundsätzlich false(). Die "compare"-Funktion gibt keinen Wert zurück.

 <vergleich_leerstring_leereSequence 
     vleererString="" 
     vleereSequence=""/>

Beide Werte werden erst vergleichbar, wenn sie explizit als string-Wert gecastet werden:

<vergleich>
  <xsl:value-of select="compare(string($vleereSequence), 
                                string($vleererString))"/>
</vergleich>

... dann macht das Resultat mehr Sinn.

   <vergleich>0</vergleich>

collations

Bei vielen Funktionen, so auch bei Vergleichen oder Sortierungen, sind die Collations noch ein Spezialthema. Es geht etwa um die Frage, ob bei dem Vergleich von Zeichenketten das "ß" und das "ss" als gleichwertig betrachtet werden soll.

Ohne weitere Zusatzinformationen behandelt ein XSL-Prozessor diesen Aufruf ...

 <xsl:template match="/" name="xsl:initial-template">
  <root>
   <xsl:value-of select="fn:compare('lassdas', 'laßdas')"/>
  </root>
 </xsl:template>

... mit diesem Ergebnis, was bedeutet, daß die Zeichenketten unterschiedlich sind:

<root>-1</root>

Die fn:compare-Funktion hat mindestens zwei (die zu vergleichenden Zeichenketten), optional drei Parameter. Dieser dritte Parameter ist eine Collation, die den XSL-Prozessor veranlaßt, den Stringvergleich zu modifizieren.

 <xsl:template match="/" name="xsl:initial-template">
  <root>
   <xsl:value-of select="fn:compare(
        'lassdas', 
        'laßdas', 
        'http://www.w3.org/2013/collation/UCA?lang=de;strength=primary')"/>
  </root>
 </xsl:template>

Mit den passenden Collation wird "ß" und das "ss" synonym behandelt, die beiden zu vergleichenden Werte sind also gleich.

<root>0</root>

fn:contains-token

fn:contains-token prüft, ob die gegebenen Zeichenkette einem Token entspricht, ggf. unter den Regeln der Callation.

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.

qrpic/compare.jpg

wg / 3. Oktober 2017




Fragen? Anmerkungen? Tips?

Bitte nehmen Sie Kontakt zu mir auf (info10@wilfried-grupe.de).



Vielen Dank für Ihr Interesse an meiner Arbeit.


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

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