günter: xsl for-each loop auf letzten durchlauf zugreifen

Hallo Forum,

Ich möchte gerne über bestimmte Elemente eines Dokumentes iterieren und bei jedem Iterationsschritt Kindelemente des aktuellen Elementes mit den Kindelelementen des vorhergehenden Iterationsschrittes vergleichen.

previous-sibling wird nicht funktionieren, da die gesuchten Elemente nicht aufeinanderfolgend im Dokument vorliegen.

Ich mach mal ein Beispiel:

xml:

  
<root>  
  <aaa>  
    <name>  
      <nachname>doe</nachname>  
      <vorname>john</vorname>  
    </name>  
    <bbb>  
      <name>  
        <nachname>miles</nachname>  
        <vorname>richard</vorname>  
      </name>  
    </bbb>  
  </aaa>  
  <ccc>  
    <ddd>  
      <eee>  
        <name>  
          <nachname>doe</nachname>  
          <vorname>tim</vorname>  
        </name>  
      </eee>  
    </ddd>  
  </ccc>  
</root>  

jetzt möchte ich gerne alle Namen haben und darüber iterieren was ja mit einem <xsl:for-each select="//name"> schnell gemacht ist.

  
<xsl:for-each select="//name">  
  ...  
</xsl:for-each>  

Das eigentlich Problem ergibt sich erst jetzt. Im Zieldokument sollen gleiche nachnamen nur einmal aussgeben werden.

also:

  
doe,  
  john  
  tim  
miles,  
  richard  

Hierfür müsste ich ja wissen, welchen wert <nachname> im vorherigen Schleifendurchlauf hatte um ihn mit dem aktuellen zu vergleichen.

Hat jemand ne Ahnung wie man sowas anstellen kann? Etliche versuche mit xsl:variable oder xsl:param sind gescheitert :(

Besten Dank
Günter

  1. Hallo Günter,

    Das eigentlich Problem ergibt sich erst jetzt. Im Zieldokument sollen gleiche nachnamen nur einmal aussgeben werden.

    Dazu sind Gruppierungstechniken geeignet, im Folgenden für XSLT 1.0 bzw. 2.0 demonstriert:

    <?xml version="1.0" encoding="UTF-8"?>  
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">  
      <xsl:key name="groupby" match="//name" use="nachname"/>  
      <xsl:template match="root">  
        <html><head><title>Test</title></head><body>  
          <xsl:for-each select="//name[generate-id() = generate-id(key('groupby',nachname)[1])]">  
            <p>  
              <strong><xsl:value-of select="nachname"/></strong>  
              <xsl:text>: </xsl:text>  
              <xsl:for-each select="key('groupby',nachname)">  
                <xsl:value-of select="vorname"/>  
                <xsl:if test="position()!=last()">  
                  <xsl:text>, </xsl:text>  
                </xsl:if>  
              </xsl:for-each>  
            </p>  
          </xsl:for-each>  
        </body></html>  
      </xsl:template>  
    </xsl:stylesheet>
    
    <?xml version="1.0" encoding="UTF-8"?>  
    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">  
      <xsl:template match="root">  
        <html><head><title>Test</title></head><body>  
          <xsl:for-each-group select="//name" group-by="nachname">  
            <p>  
              <strong><xsl:value-of select="nachname"/></strong>  
              <xsl:text>: </xsl:text>  
              <xsl:for-each select="current-group()">  
                <xsl:value-of select="vorname"/>  
                <xsl:if test="position()!=last()">  
                  <xsl:text>, </xsl:text>  
                </xsl:if>  
              </xsl:for-each>  
            </p>  
          </xsl:for-each-group>  
        </body></html>  
      </xsl:template>  
    </xsl:stylesheet>
    

    Grüße,
    Thomas