XPath 3.0, XPath 2.0, XPath 1.0 / XPath-Funktionen / Stringfunktionen / XPath: starts-with

XPath: starts-with

XPath: starts-with

➪ Die starts-with-Funktion prüft, ob ein Item (das als String gecastet werden kann) mit einer bestimmten Zeichenfolge beginnt.

Da sie einen Boolean-Wert true() oder false() zurückgibt, kann sie sowohl im Rahmen von Fallunterscheidungen (, ) als auch als Prädikat in XPath eingesetzt werden.


<xsl:variable name="y" as="xs:string+">
  <xsl:for-each 
    select="('Meier', 'Schulze', 'Müller', 'Schmidt', 5)
            [starts-with(xs:string(.), 'Sch')]">
   <xsl:value-of select="."/>
  </xsl:for-each>
</xsl:variable>
<xsl:value-of select="string-join($y, '|')"/>

Resultat:


Schulze|Schmidt

Kann ein Item nicht automatisch als gecastet werden, so wird ein Fehler generiert (s.u.). Daher empfiehlt sich zur Sicherheit (wie oben geschehen), den zu prüfenden Wert ausdrücklich als String zu casten:


starts-with(xs:string(.), 'Sch')
bzw.
starts-with(string(.), 'Sch')

Geschieht das nicht, so wird die Zahl 5 (die kein String in diesem Sinn ist) in der starts-with-Funktion (die zwingend einen Stringparameter erwartet) einen Fehler verursachen.


<xsl:for-each 
  select="('Meier', 'Schulze', 'Müller', 'Schmidt', 5)
          [starts-with(., 'Sch')]">
...

Die aussagekräftige Fehlermeldung sieht so aus:


Fehlerlevel: fatal
Beschreibung: XPTY0004: 
Required item type of first argument of starts-with() 
is xs:string; supplied value has item type xs:integer
URL: http://www.w3.org/TR/xpath20/#ERRXPTY0004

starts-with ist das Gegenstück der -Funktion.

starts-with und local-name

Es gibt noch einen anderen Fall, wo die starts-with-Funktion gern eingesetzt wird und wo, wie ich finde, Vorsicht angebracht ist. Nehmen Sie an, Sie hätten es mit unterschiedlichen Dokumentstrukturen zu tun, deren Elementnamen eine Gemeinsamkeit aufweisen. Beispiele:


<Orte2018>
  <Ort>
    <Mensch name="Schlaflos"/>
  </Ort>
</Orte2018>

oder


<Orte2019>
  <Ort>
    <Mensch Nachname="Wunschlos"/>
  </Ort>
</Orte2019>

oder


<OrteInDeutschland>
  <Ort>
    <Mensch>
      <name>Traumschlos</name>
    </Mensch>
  </Ort>
</OrteInDeutschland>

Die Root-Elemente dieser Beispiele beginnen einheitlich mit "Orte", sie können alle mit dem folgenden XSL-Stylesheet angesprochen werden, bei dem der Name des Root-Elements nicht klar benannt, sondern zur Laufzeit ermittelt und daraufhin geprüft wird, ob er mit dem Teilstring "Orte" beginnt. Die Kombination der XPath-Funktionen starts-with und ermöglicht das.


<xsl:for-each 
     select="/*[starts-with(local-name(), 'Orte')]/Ort/Mensch">
...
</xsl:for-each>

Haben Sie es mit abweichenden Dokumentstrukturen zu tun (was vermutet werden kann, wenn die Elemente andere Namen haben), dann ist unbedingt zu prüfen, ob die Voraussetzungen der verwendeten XSL-Programmierlogik noch mit der Input-XML-Dokumentstruktur übereinstimmen. Nur unter dieser Voraussetzung sollten starts-with(local-name()) bzw. starts-with(name()) oder ähnliche Konzepte zum Einsatz kommen.

Es ist möglich, dass sich hinter den unterschiedlichen Namen der Root-Elemente Versionsunterschiede verbergen, mit denen abweichende XML-Dokumentstrukturen auf tieferen Ebenen verbunden sind. Sei es, dass die Childnodes anders benannt werden ( oder ), Attribute statt Elemente oder überhaupt andere Inhalte übermittelt werden.

Konkret besteht die Gefahr, dass die Versionsunterschiede, die im Root-Element abgesichert werden sollen, durch die Teilprüfung des Elementnamens übersehen werden. Während die XML-Dokumentstruktur sich geändert hat, setzt die XSL-Programmierung auf einer früheren Version auf. Die neue Dokumentstruktur wird nicht korrekt adressiert. Die wahrscheinliche Folge ist Informationsverlust, der teure Konsequenzen nach sich ziehen kann.

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