1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen

XSLT - "Fehler" abfangen ...

Dieses Thema im Forum "XML Technologien" wurde erstellt von mne, 14. März 2013.

  1. mne

    mne Grünschnabel

    Hallo allseits,

    ich habe ein XML welches (stark verkuerzt) wie folgt aussieht:
    Code (XML):
    1. <model><sources>
    2.     <source home="String1_String2">
    3.         <abos>
    4.             <abo name="abo1" />
    5.             <abo name="abo2" />
    6.         </abos>
    7.     </source>
    8. </sources></model>
    Und muss daraus ein File wie folgt generieren:
    Code (Text):
    1. String2-abo1
    2. String2-abo2
    Dazu habe ich mir folgendes xslt gebastelt, welches auch ganz gut funktioniert:

    Code (XML):
    1. <?xml version="1.0"?>
    2. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    3.  
    4. <xsl:output method="text" />
    5.  
    6. <xsl:template match="/model/sources/source/abos/abo">
    7.     <xsl:value-of select="concat(substring-after(../../@home,'_'),'-')" />
    8.     <xsl:value-of select="concat(@name,'
    9. ')" />
    10. </xsl:template>
    11.  
    12. <xsl:template match="text()" />
    13.  
    14. </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:

    Code (XML):
    1. <?xml version="1.0"?>
    2. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    3.  
    4. <xsl:output method="text" />
    5.  
    6. <xsl:template match="/model/sources/source/abos/abo">
    7.     <xsl:choose>
    8.         <xsl:when test="matches(../../@home,'_')" >
    9.             <xsl:value-of select="concat(substring-after(../../@home,'_'),'-')" />
    10.             <xsl:value-of select="concat(@name,'
    11. ')" />
    12.         </xsl:when>
    13.         <xsl:otherwise>
    14.             <xsl:message terminate="yes">Fehler!</xsl:message>
    15.         </xsl:otherwise>
    16.     </xsl:choose>  
    17. </xsl:template>
    18.  
    19. <xsl:template match="text()" />
    20.  
    21. </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 von einem Moderator bearbeitet: 23. Mai 2014
  2. hela

    hela Premium-User

    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:
    Code (XML):
    1. <?xml version="1.0"?>
    2. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    3.  
    4. <xsl:output method="text" />
    5.  
    6. <xsl:template match="//source">
    7.   <xsl:apply-templates select="abos/abo">
    8.     <xsl:with-param name="homeText">
    9.       <xsl:choose>
    10.         <xsl:when test="contains(@home,'_')">
    11.           <xsl:value-of select="substring-after(@home,'_')" />
    12.         </xsl:when>
    13.         <xsl:otherwise>
    14. <!--
    15.          <xsl:message terminate="yes">Fehler!</xsl:message>
    16. -->
    17.           <xsl:value-of select="@home" />
    18.  
    19.         </xsl:otherwise>
    20.       </xsl:choose>
    21.     </xsl:with-param>
    22.   </xsl:apply-templates>
    23. </xsl:template>
    24.  
    25. <xsl:template match="abo">
    26.   <xsl:param name="homeText" />
    27.   <xsl:value-of select="concat($homeText,'-',@name,'
    28. ')" />
    29. </xsl:template>
    30.  
    31. <xsl:template match="text()" />
    32.  
    33. </xsl:stylesheet>
     
    Zuletzt von einem Moderator bearbeitet: 23. Mai 2014
    mne gefällt das.
  3. deepthroat

    deepthroat Erfahrenes Mitglied

    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.
     
    mne gefällt das.
  4. mne

    mne Grünschnabel

    Hallo hela!


    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
     
  5. hela

    hela Premium-User

    Ich verwende SelfHTML>XML/DTDs>XSLT-Elemente und >XPath-Funktionen meistens zum Nachschlagen. Wenn ich nicht irre, dann ist das bedingt durch das Alter der Quelle alles XPath1 und XSLT1.
    Eine etwas ausführlichere Referenz getrennt nach XSLT1 und XSLT2 gibt es bei data2type.
     
    mne gefällt das.
  6. mne

    mne Grünschnabel

    Hallo hela,

    alles klar, bei mir funkt alles - herzlichen Dank nochmals!

    LG., Michael
     
Die Seite wird geladen...