Announcement

Collapse
No announcement yet.

Testen eines vorhergehenen Elementes (XSLT, XPath)

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

  • Testen eines vorhergehenen Elementes (XSLT, XPath)

    Ich habe Probleme beim Testen eines vorhergehenen Elementes auf der preceding-sibling-Achse. Ziel soll es sein aus einen para-Element ein para_1-Element zu machen, falls dem ein ueberschrift-Element direkt vorausgeht.

    Folgender XML-Code liegt zum Beispiel vor:

    Code:
    <abschnitt>
      <abschnitt>
        <para>Text</para>
        <para>Text</para>
      </abschnitt>
      <abschnitt>
        <ueberschrift>Text</ueberschrift>
        <para>Text</para>    <!-- soll zu <para_1> werden-->
        <para>Text</para>
        <ueberschrift>Text</ueberschrift>
        <para>Text</para>    <!-- soll zu <para_1> werden-->
        <para>Text</para>
        <para>Text</para>
      </abschnitt>
    </abschnitt>

    Dazu das XSL-Template, was leider nicht seine eigentliche Funktion tut, da der Test fehlschlägt.
    Code:
    <xsl:template match="para">
      <xsl:choose>
        <xsl:when test="preceding-sibling::node()[position()-1][ueberschrift]"> <!-- Hier der XPath-Ausdruck - das Problem -->
          <para_1><xsl:copy-of select="node()"/></para_1>
        </xsl:when>
        <xsl:otherwise>
          <para><xsl:copy-of select="node()"/></para>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:template>
    Ich habe schon x Sachen ausprobiert - ich weiß einfach nicht weiter

  • #2
    Es erschwert die Auswertung wenn
    ein Unterknoten den selben Namen hat

    Datei zum Testen
    Code:
    <?xml version="1.0"?>
    <abschnitt>
    	<abschnitt>
    		<para>Text1</para>
    		<para>Text2</para>
    	</abschnitt>
    	<abschnitt>
    		<ueberschrift>Text</ueberschrift>
    		<para>Text to para_1</para>
    		<!-- soll zu <para_1> werden-->
    		<para>Text3</para>
    		<ueberschrift>Text</ueberschrift>
    		<para>Text_to para_1</para>
    		<!-- soll zu <para_1> werden-->
    		<para>Text4</para>
    		<para>Text5</para>
    	</abschnitt>
    </abschnitt>

    Code:
    <?xml version="1.0"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    	<xsl:output indent="yes" method="xml"/>
    	<xsl:template match="/">
    		<abschnitt>
    			<xsl:apply-templates select="/abschnitt/abschnitt"/>
    		</abschnitt>
    	</xsl:template>
    	
    
    	<xsl:template match="abschnitt">
    		<abschnitt>
    			<xsl:for-each select="*">
    				<xsl:variable name="test" select="name()"/>
    				<xsl:variable name="kn" select="local-name(preceding::*[1])"/>
    				
    				<xsl:choose>
    
    					<xsl:when test="$test='ueberschrift'">
    						<ueberschritt>
    							<xsl:value-of select="."/>
    						</ueberschritt>
    					</xsl:when>
    					<xsl:when test="$kn='ueberschrift'">
    						<para_1>
    							<xsl:value-of select="."/>
    						</para_1>
    					</xsl:when>
    					<xsl:when test="$test='para'">
    						<para>
    							<xsl:value-of select="."/>
    						</para>
    					</xsl:when>
    				</xsl:choose>
    			</xsl:for-each>
    		</abschnitt>
    	</xsl:template>
    </xsl:stylesheet>
    ergebnis

    Code:
    <?xml version='1.0' ?>
    <abschnitt>
      <abschnitt>
        <para>Text1</para>
        <para>Text2</para>
      </abschnitt>
      <abschnitt>
        <ueberschritt>Text</ueberschritt>
        <para_1>Text to para_1</para_1>
        <para>Text3</para>
        <ueberschritt>Text</ueberschritt>
        <para_1>Text_to para_1</para_1>
        <para>Text4</para>
        <para>Text5</para>
      </abschnitt>
    </abschnitt>
    Zuletzt editiert von xml-looser; 24.12.2009, 11:16.

    Comment


    • #3
      Danke für die Antwort. Habe mittlerweile einen Umweg um dieses Problem gemacht, was jedoch nicht mehr viel mit dem Eigentlichen hier zu tun hat.

      Deine Lösung habe ich in einem Template für para-Knoten ausprobiert und es klappt wunderbar. Das mit den verschachtelten Abschnitten war hier eher nebensächlich - diente nur dem Testen, also um bestimmte Fehler auszuschließen.

      Code:
      <xsl:template match="para">
        <xsl:variable name="test" select="name(preceding-sibling::*[1])" />
        <xsl:choose>
          <xsl:when test="$test='ueberschrift'">
            <para_1><xsl:copy-of select="node()"/></para_1>
          </xsl:when>
          <xsl:otherwise>
            <para><xsl:copy-of select="node()"/></para>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:template>

      Comment

      Working...
      X