Announcement

Collapse
No announcement yet.

Kann man das ermöglichen: <xsl:template match="$para-element"> ...

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Kann man das ermöglichen: <xsl:template match="$para-element"> ...

    Hallo an alle!

    Ich möchte gern ein bestimmtes Element verarbeiten, dessen Name und Eigenschaften mir aber erst zur Kompilierung des Stylesheets übergeben werden. Soweit ich es recherchieren konnte erlaubt XSLT keine Variablen in match-Kriterien, oder? Saxon9 bringt dann jedenfalls einen Fehler.

    Ich habe auch versucht das Element an sich statisch im match zu adressieren und in der template ein choose auf bestimmte Attributwerte zu machen. Diese Funktionalität würde mir auch reichen. Allerdings möchte ich dort wiederrum auf beliebig viele extern bestimmte Werte testen können. Quasi so:

    Code:
    <xsl:when test="$para-conditions"
    para-conditions könnte dann sein:
    Code:
    @name='Mr. X'
    oder aber auch ein komplexerer Ausdruck wie:
    Code:
    @name='Mr. X' or @name='Mrs. Y'
    Ich muss irgendwie offen lassen können, welches Element transformiert werden soll. Habt ihr Ideen? Bisher bin ich immer gescheitert.

    Viele Grüße,
    Martin

  • #2
    Versuche die Parameter-Strings in Prädikaten unterzubringen, also innerhalb von [...]. Zeige ansonsten konkreten Code und vielleicht lässt sich das auch anders lösen.

    Comment


    • #3
      Vielen Dank für den Hinweis. Ich kann jetzt Variablen im match des templates unterbringen. Saxon9 bringt keine Fehler mehr, wenn ich es so schreibe. Hier kurz ein Überblick zu meinem Vorhaben:

      Code:
      XML:
      <Image name="homer">c:\images\homer.jpg</Image>
      <Image name="marge">c:\images\marge.jpg</Image>
      <Image name="lisa">c:\images\lisa.jpg</Image>
      <Image name="bart">c:\images\bart.jpg</Image>
      
      
      XSLT:
      <xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" version="2.0">
      
        <xsl:variable name="var-target-name" select="@name='homer'" />
      
        <xsl:template match="//Image[$var-target-name]">
          <...
        </xsl:template>
      
      </xsl:stylesheet>
      Leider funktioniert das noch nicht richtig. Saxon9 interpretiert die übergebene Variable nicht oder einfach falsch. Es gibt da verschiedene Ergebnisse:

      - select="@name='homer'" -> kein Element wird transformiert
      - select="@name='homer' or 'marge'" -> alle Elemente werden transformiert
      - select="homer" -> kein Element wird transformiert
      - select="'homer'" -> alle Elemente werden transformiert

      Schreibe ich aber:
      Code:
      <xsl:template match="//Image[@name='homer']">
      funktioniert alles und es wird nur Homer transformiert. Mein Ziel ist es immernoch eine template variabel lassen zu können. Aber XSLT+Saxon wehren sich heftig. Gibt es dafür eine Erklärung oder Lösungen?
      Zuletzt editiert von bassspieler; 21.04.2008, 11:34.

      Comment


      • #4
        Gib doch mal den Inhalt von $var-target-name aus, da steht einfach nichts drin. Es funktioniert so nicht. XPath-Ausdrücke müssen direkt zugewiesen werden, wobei Zeichenketten (Knotennamen, Knoteninhalte) wiederum in Prädikaten verglichen werden können.

        Folgende Abfrage ist möglich:
        <xsl:value-of select="Image[attribute::*[local-name()='name'][.='homer']]"/>

        Wenn also eine Variable diesen Inhalt hat (in '...' und ohne @):
        <xsl:variable name="var-target-name" select="'name=homer'" />

        nimmt die genannte Zeile diese Form an:

        <xsl:value-of select="Image[attribute::*[local-name()=substring-before($var-target-name,'=')][.=substring-after($var-target-name,'=')]]"/>

        Somit können dynamisch Attributnamen und -werte übergeben und abgefragt werden.
        Zuletzt editiert von Thomas Meinike; 21.04.2008, 14:39.

        Comment


        • #5
          Die Kunst ist es folglich: @name='homer' als String, also uninterpretiert, in select="XXX" hineinzuschreiben. Ich habe bisher versucht die Bildungsvorschriften
          [74] StringLiteral ::= ('"' (EscapeQuot | [^"])* '"') | ("'" (EscapeApos | [^'])* "'")
          [75] EscapeQuot ::= '""'
          [76] EscapeApos ::= "''"
          für Strings zu verstehen, um die umgebenden ' bei homer escapen zu können, aber das funktioniert nicht. Lasse ich diesen Gedanken weg und schreibe nur

          Code:
          select="'@name=homer'"
          nimmt er das erstmal als String -> das @ ist also nicht das Problem. Schreibe ich aber
          Code:
          select="@name='homer'"
          ist der Wert der Variable das Bool "false".

          Comment


          • #6
            Wenn in Variablen XPath-Ausdrücke stehen, werden diese ausgewertet, also als Strings, Numbers oder Booleans. Stehen vermeintliche XPath-Ausdrücke innerhalb von '...' bleiben es Zeichenketten, die aber bei match oder select selbst nicht auswertbar sind. Bleibt also nur die von mir genannte Form als (Teil-)Zeichenketten innerhalb von Prädikaten.

            Ein Attribut name mit Inhalt 'homer' wäre eher so abzufragen: @name[.='homer']

            Ich schrieb auch nicht, dass das @ ein Problem wäre, sondern in der Konstellation 'name=homer' nicht benötigt wird, da der Inhalt vor dem = als Attribut name mittels attribute-Achse und der Inhalt nach dem = als Wert dieses Attributes fungiert: attribute::name entspricht ja @name.
            Zuletzt editiert von Thomas Meinike; 21.04.2008, 15:50.

            Comment


            • #7
              Vielen vielen Dank für deine ausführliche Hilfe! Noch komme ich hinterher. Aber ich hätte nie gedacht, dass es so umständlich wird. Darum stottere ich noch ein wenig umher.

              Ich bin jetzt soweit:
              Code:
              <xsl:template match="//Image[attribute::*[local-name()=substring-before( $var-target, '=')][.=substring-after( var-target, '=')]]">
              Saxon meint aber dazu:
              The child axis starting at an attribute will never select anything.
              und prompt wird auch die template nicht angewandt.

              Comment


              • #8
                Mit Deinem Beispiel + Wurzelelement Images funktioniert dieser Test:

                Code:
                <?xml version="1.0" encoding="UTF-8"?>
                <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
                  <xsl:output method="html" version="4.01" encoding="UTF-8" indent="yes"/>
                  
                  <xsl:variable name="var-target-name" select="'name=homer'" />
                
                  <xsl:template match="Images">
                    <xsl:value-of select="Image[attribute::*[local-name()=substring-before($var-target-name,'=')][.=substring-after($var-target-name,'=')]]"/>
                  </xsl:template>
                
                </xsl:stylesheet>
                mit dem Ergebnis unter Saxon 9.0B: c:\images\homer.jpg

                Passe also die Template-Hierarchien entsprechend an.
                Zuletzt editiert von Thomas Meinike; 21.04.2008, 16:06.

                Comment


                • #9
                  Mein Problem ist denke ich ein anderes. Ich versuche ein template variabel auf Elementattribute matchen zu lassen. Die ausgelöste Transformation soll später den jeweiligen Image-Tag restrukturieren. Der Rest der XML-Daten soll 1:1 kopiert werden. Meine zu findenden Bild-Tags sind heterogen über eine große XML-Datei verteilt, also nicht unter einem <Images> zusammengefasst.
                  Code:
                  XMLalt:
                  <Image name="homer">c:\images\homer.jpg</Image>
                  <Image name="marge">c:\images\marge.jpg</Image>
                  <Image name="lisa">c:\images\lisa.jpg</Image>
                  <Image name="bart">c:\images\bart.jpg</Image>
                  
                  XMLneu:
                  XML:
                  <Image name="homer"><MetaInfo select="vater" />c:\images\homer.jpg</Image>
                  <Image name="marge">c:\images\marge.jpg</Image>
                  <Image name="lisa">c:\images\lisa.jpg</Image>
                  <Image name="bart">c:\images\bart.jpg</Image>
                  Das mit einer template zu erreichen, der ich variabel sagen kann, welcher der Personen Metadaten (auch über Variablen verfügbar) zugefügt werden sollen ist mein großes Ziel.

                  Comment


                  • #10
                    Das war nur ein Beispiel, um die Funktionsfähigkeit des Ansatzes zu zeigen. Baue diesen entsprechend aus.

                    Comment


                    • #11
                      Dankeschön!

                      Die Fehlerausgabe vom Saxon hat mich zu sehr abgelenkt. Letztendlich hat es genau so geklappt, wie von dir vorgeschlagen.
                      Um noch kurz auf meinen eigentlichen Traum zu sprechen zu kommen:
                      Code:
                      <xsl:template match="$pattern">
                      Das kann nicht gehen, oder?

                      Vielen Dank für die Hilfe,
                      Martin

                      Comment


                      • #12
                        Es wird bei match ein Pattern und eben keine Variable oder Parameter mit einem String-Literal erwartet. Die alternative Nutzung von Prädikaten hatte ich ja beschrieben.

                        Bei der Nutzung von Saxon könnten allerdings die Erweiterungsfunktionen saxon:evaluate() bzw. saxon:expression() helfen.

                        Comment

                        Working...
                        X