CyTom: XSLT: Selektive Ausgabe von TextNodes

Also mein Problem ist, dass ich gerne den Text innerhalb eines Tags ausgeben würde. Allerdings nur den Text, der direkt in dem Tag steht und nicht den Text, der innerhalb untergeordneter Knoten steht.

Beispiel:

--XML--
<newseintrag>
  <text>
    diese meldung wurde von
    <a>
      <url>mailto:xyz@xyz.xyz</url>
      <name>xyz</name>
    </a>
    geposted
  </text>
</newseintrag>

--XSL--
<xsl:template match="text">

<xsl:value-of select="node()" />

<xsl:apply-templates select="*" />

</xsl:template>

--HTML--
diese meldung wurde von <XYZ>

Ok, das liegt wohl daran, dass ich nur den ersten Text mit "node()" ausgebe, aber ich weiß nicht wie man z.B. alle TextNodes durchlaufen kann und nur die auswählt, die child von <text> sind und dann noch an den richtigen Stellen die anderen enthaltenen Elemente ausgibt.

Eine Möglichkeit scheint mir das Verpacken der TextBausteine in einzelne Tags, die dann auf einfachste Art und Weise ausgegeben werden können.

Doch ich würde es nun mal liebend gerne auf die von mir beschriebene Art machen, allein schon deshalb, damit ich meine XML-Datei nicht ändern muss.

Ich würde mich über eine Antwort sehr freuen
Thomas

  1. Hallo Thomas,

    Also mein Problem ist, dass ich gerne den Text innerhalb eines Tags ausgeben würde. Allerdings nur den Text, der direkt in dem Tag steht und nicht den Text, der innerhalb untergeordneter Knoten steht.

    <newseintrag>
      <text>
        diese meldung wurde von
        <a>
          <url>mailto:xyz@xyz.xyz</url>
          <name>xyz</name>
        </a>
        geposted
      </text>
    </newseintrag>

    Wenn du wirklich nur die Textknoten in der Reihenfolge ausgeben willst, wie Sie in der XML-Datei aufeinander folgen (also in sogenannter Dokumentordnung), dann musst du eigentlich nur in einer Template Rule für den Wurzelknoten das Grundgerüst für die HTML-Datei erzeugen und xsl:apply-templates/ aufrufen. Dann sucht der XSLT-Prozessor nach Template Rules für die Kindknoten des Wurzelknotens. Findet er keine Template Rules für diese Knoten, greifen sogenannte eingebaute Template Rules (Standard-Regeln, wenn man so will). Bei Elementknoten wird erneut xsl:apply-templates/ aufgerufen und bei den Textknoten wird dann der Zeichenkettenwert des Knotens ausgegeben.

    Expliziter wird dieses Verhalten, wenn du eine Template Rule für alle Textknoten schreibest.

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="/">
        <html>
           <head>
             <title>Alle Textknoten in Dokumentenordnung ausgeben</title>

    </head>
           <body>
             <p>

    xsl:apply-templates/
             </p>

    </body>
         </html>
      </xsl:template>

    <!-- Aufgrund der eingebauten Template Rules kann diese Template Rule eigentlich auch weggelassen werden -->
      <xsl:template match="text()">

    <xsl:value-of select="."/>

    </xsl:template>

    </xsl:stylesheet>

    Mit node() selektierst du alle Knotentypen mit text() nur die Textknoten

    Ich vermute mal, dass Du aber den Namen ausgeben willst mit einem Link dahinter. Dass ginge dann mit folgendem Stylesheet:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="/">
        <html>
           <head>
             <title>Alle Textknoten in Dokumentenordnung ausgeben</title>

    </head>
           <body>
             <p>

    xsl:apply-templates/
             </p>

    </body>
         </html>
      </xsl:template>

    <xsl:template match="text">

    <xsl:value-of select="text()[1]"/>
             <a href="{a/url}">
               <xsl:value-of select="a/name"/>
             </a>
             <xsl:value-of select="text()[2]"/>

    </xsl:template>

    </xsl:stylesheet>

    Nicht sehr elegant, aber recht einfach. Über ein Prädikat suchst du Dir zunächst den ersten Textknoten unterhalb des Elements <text> raus, dann erzeugst du über Attribute Value Templates den Link und schließlich hängst Du den zweiten Textknoten dran. Funktioniert natürlich nur, wenn die Struktur der XML-Datei immer so ist.

    Gruß
    Franz