XSLT - "Fehler" abfangen ...

mne

Grünschnabel
Hallo allseits,

ich habe ein XML welches (stark verkuerzt) wie folgt aussieht:
XML:
<model><sources>
    <source home="String1_String2">
        <abos>
            <abo name="abo1" />
            <abo name="abo2" />
        </abos>
    </source>
</sources></model>

Und muss daraus ein File wie folgt generieren:
Code:
String2-abo1
String2-abo2

Dazu habe ich mir folgendes xslt gebastelt, welches auch ganz gut funktioniert:

XML:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 
<xsl:output method="text" />

<xsl:template match="/model/sources/source/abos/abo">
    <xsl:value-of select="concat(substring-after(../../@home,'_'),'-')" />
    <xsl:value-of select="concat(@name,'
')" />
</xsl:template>
 
<xsl:template match="text()" />
 
</xsl:stylesheet>

Leider passiert es aber, dass im "home"-Attribute KEIN "_" vorhanden ist. Das sollte als Fehler behandelt werden, die Transformation dürfte bei einem solchen (fuer mich) fehlerhaften Wert auch abbrechen.

Also hab ich obiges xslt wie folgt verändert:

XML:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 
<xsl:output method="text" />

<xsl:template match="/model/sources/source/abos/abo">
    <xsl:choose>
        <xsl:when test="matches(../../@home,'_')" >
            <xsl:value-of select="concat(substring-after(../../@home,'_'),'-')" />
            <xsl:value-of select="concat(@name,'
')" />
        </xsl:when>
        <xsl:otherwise>
            <xsl:message terminate="yes">Fehler!</xsl:message>
        </xsl:otherwise>
    </xsl:choose>	
</xsl:template>
 
<xsl:template match="text()" />
 
</xsl:stylesheet>

Nur kann er das nicht kompilieren, er bricht mit folgender Fehlermeldung ab:
Error! Fehler beim Überprüfen des Typs des Ausdrucks 'funcall(matches, [ParentLocationPath(ParentLocationPath(step("parent", -1), step("parent", -1)), step("attribute", 19)), literal-expr(_)])'.

Wäre nett wenn mir jemand sagen könnte, was ich da falsch mache (oder ev. auch wie man das besser löst), herzlichen Dank!

LG., mne
 
Zuletzt bearbeitet von einem Moderator:
...
Nur kann er das nicht kompilieren, er bricht ...
Hallo, wer ist "er"?

  • Die Funktion matches() ist XPath2.0 und wird (bei mir hier) nur von Saxon9.2 unterstützt. Statt dessen kannst du aber gleichwertig die Funktion contains() verwenden. Siehe auch hier: Pattern Matching with XSLT
  • Ahnlich verhält es sich mit der Funktion xsl:message, da verhält sich jeder XSLT-Prozessor anders und ich vermeide deshalb möglichst diese Funktion.
Abgesehen davon würde ich den Inhalt des home-Attributes in der source-Ebene ermitteln und als Parameter weitergeben, etwa so:
XML:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="text" />

<xsl:template match="//source">
  <xsl:apply-templates select="abos/abo">
    <xsl:with-param name="homeText">
      <xsl:choose>
        <xsl:when test="contains(@home,'_')">
          <xsl:value-of select="substring-after(@home,'_')" />
        </xsl:when>
        <xsl:otherwise>
<!--
          <xsl:message terminate="yes">Fehler!</xsl:message>
-->
          <xsl:value-of select="@home" />

        </xsl:otherwise>
      </xsl:choose>
    </xsl:with-param>
  </xsl:apply-templates>
</xsl:template>

<xsl:template match="abo">
  <xsl:param name="homeText" />
  <xsl:value-of select="concat($homeText,'-',@name,'
')" />
</xsl:template>

<xsl:template match="text()" />

</xsl:stylesheet>
 
Zuletzt bearbeitet von einem Moderator:
  • Gefällt mir
Reaktionen: mne
Hi.

"matches" ist eine Funktion des XSLT 2.0 Standards.

Der Standard XSLT Java Prozessor (XALAN-J?) unterstützt nur XSLT 1.0.

Statt matches kannst du einfach die XSLT 1.0 (XPath 1.0) Funktion "contains" verwenden.
 
  • Gefällt mir
Reaktionen: mne
Hallo hela!

Hallo, wer ist "er"?

  • Die Funktion matches() ist XPath2.0 und wird (bei mir hier) nur von Saxon9.2 unterstützt. Statt dessen kannst du aber gleichwertig die Funktion contains() verwenden. Siehe auch hier: Pattern Matching with XSLT
  • Ahnlich verhält es sich mit der Funktion xsl:message, da verhält sich jeder XSLT-Prozessor anders und ich vermeide deshalb möglichst diese Funktion.


Verstehe, alles klar. Ich binde hier die Bibliothek saxon8.jar ein, also vermute ich stark, daß ich Saxon 8 verwende und somit XPath2.0 bei mir wirklich noch nicht vollständig (oder gar nicht) unterstützt wird.

Anscheinend verwende ich hier auch die falsche Dokumentation. Ich hab mir die verwendeten XPath-Funktionen von hier abgeguckt: http://www.w3schools.com/xpath/xpath_functions.asp#string, da wird tatsächlich auf XPath2.0 Bezug genommen.

Zur Parameterübergabe: Danke für die Anregung! Ich bin noch blutiger Anfänger was xslt betrifft, da nehme ich Dein xslt gleich als Anregung/Beispiel, um mir die Parameterübergabe genauer anzusehen. :)

Unabhängig davon - Obige URL auf w3schools stammt von der LinkListe hier im Forum (In der FAQ). Hätte ev. jemand eine URL, die halbwegs übersichtlich auf XPath1.0-Funktionen verweist, damit ich nicht öfters mit alten/neuen Funktionen Troubles habe?


Danke u. LG., Michael
 
Zurück