Announcement

Collapse
No announcement yet.

String, abhängig von Kindelement, aufteilen

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

  • String, abhängig von Kindelement, aufteilen

    Code:
    <text typ="Inhalt">Hier steht ein Text.<abschnitt/> Ein weiterer Text. <abschnitt/> - Und noch ein Text. <abschnitt/> Die letzte Zeile.</text>
    Hallo!
    Wie kann ich im obigen Beispiel abfragen, welcher Text einem Element <abschnitt> (bis zum nächsten <abschnitt>) folgt.
    Wenn ich das Elternelement von <abschnitt> abfrage, ist das ja immer der gesamte Text von <text typ="Inhalt">.
    Wie kann ich diesen Text am besten in mehrere Strings aufteilen und individuell behandeln?

    Gruß, Peter

  • #2
    Mit XSLT 2.0 und for-each-group
    Code:
    <xsl:template match="text[@typ = 'Inhalt']">
      <xsl:for-each-group select="node()" group-starting-with="abschnitt">
         <xsl:apply-templates select="current-group()[self::text()]"/>
      </xsl:for-each-group>
    </xsl:template>
    Das apply-templates innerhalb des for-each-group ist nur ein Beispiel, um dann die gruppierten Knoten weiter zu verarbeiten.

    Mit XSLT 1.0 und der recht simplen Struktur kann man eventuell auch einfach alle "abschitt"-Elemente verarbeiten und dann per following-sibling-Achse auf die Textknoten zugreifen, also etwa
    Code:
    <xsl:template match="text[@typ = 'Inhalt']">
      <xsl:apply-templates select="abschnitt"/>
    </xsl:template>
    
    <xsl:template match="abschnitt">
      <xsl:apply-templates select="following-sibling::node()[1][self::text()]"/>
    </xsl:template>
    Während das for-each-group aber den ersten Textknoten "Hier steht ein Text." gruppiert und verarbeitet, wird dieser bei obigem einfachen XSLT 1.0-Ansatz nicht verarbeit; man müsste eventuell das erste Template erweitern:
    Code:
    <xsl:template match="text[@typ = 'Inhalt']">
      <xsl:apply-templates select="text()[not(preceding-sibling::node()[self::abschnitt])] | abschnitt"/>
    </xsl:template>

    Comment


    • #3
      Es lässt sich auf die einzelnen Textknoten mit text()[1] usw. zugreifen. Hier mal beispielhaft mit xsl:for-each und einer Liste demonstriert:
      [highlight=xml]<ul>
      <xsl:for-each select="text[@typ = 'Inhalt']/text()">
      <li><xsl:value-of select="."/></li>
      </xsl:for-each>
      </ul>[/highlight]

      Ergebnis:

      HTML Code:
      <ul>
        <li>Hier steht ein Text.</li>
        <li> Ein weiterer Text. </li>
        <li> - Und noch ein Text. </li>
        <li> Die letzte Zeile.</li>
      </ul>

      Comment


      • #4
        Vielen Dank für die Antworten!
        Das war mir nicht bewusst, dass es sich ja schon um verschiedene Textknoten handelt, die mit text()[1] usw. angesprochen werden können.
        Habe gerade entdeckt, dass der XPath Analyzer von XMLSpy in dieser Richtung wertvolle Dienste leisten kann...

        Comment

        Working...
        X