XPath 3.0, XPath 2.0, XPath 1.0 / XPath-Funktionen / Stringfunktionen / XPath: compare

XPath: compare

XPath: compare

➪ Die compare-Funktion vergleicht zwei Stringparameter miteinander.

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 Sie 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 Sie v1 mit v1:


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

das Ergebnis ist 0.


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

Vergleichen Sie 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 Sie hier.

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

Hier bleibt noch anzumerken, dass häufig im Rahmen von Fallunterscheidungen (, ) 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 hier der Vergleich von leeren Strings mit leeren Sequenzen. In diesem Fall gibt die compare-Funktion keinen Wert zurück. Erst ein explizites Casting der Parameter als String ergibt das Resultat "0".


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

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


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

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


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

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


 <vergleich_leerstring_leereSequenz 
     vleererString="" 
     vleereSequenz=""/>

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


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

... dann macht das Resultat mehr Sinn.


<vergleich>0</vergleich>

collations

Bei vielen Funktionen, so auch bei Vergleichen oder Sortierungen, sind Collations 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="/">
  <root>
   <xsl:value-of 
        select="fn:compare('lassdas', 'laßdas')"/>
  </root>
</xsl:template>

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


<root>-1</root>

Die compare-Funktion hat mindestens zwei (die zu vergleichenden Zeichenketten), optional drei Parameter. Dieser dritte Parameter ist eine Collation (http://www.w3.org/2013/collation/UCA?lang=de;strength=primary), die den XSL-Prozessor veranlasst, den Stringvergleich zu modifizieren.


<xsl:template match="/">
  <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 der passenden Collation wird "ß" und das "ss" synonym behandelt, die beiden zu vergleichenden Werte sind also gleich.


<root>0</root>

wg / 4. April 2018



Fragen? Anmerkungen? Tips?

Bitte nehmen Sie Kontakt zu mir auf.






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/compare.html