Thomas J.S.: XSLT-Sortierung / Zusammenfasssung nach Elementnamen

Beitrag lesen

Hallo Jens,

hier das versprochene XSLT. Wenn Dir was negativ auffältt, lass es mich wissen:

vorneweg: es ist eine gute Lösung.
Das Problem wobei in anstehe - auf Grund, dass ich dein XML und die zu erwartenden Möglichkeiten nicht kenne - ist:
deine Lösung funktioniert unter zwei Voraussetzungen:

  1. alle Gruppen in der key('folgenr') haben die selbe anzahl von Table-Elementen
  2. alle Table-Elemente in dieser Gruppe haben die selben Zuordnungen

d.h. wenn deine Tabelle so aussieht:

.   A   B   C
-------------
1   x   x   x
-------------
2   x   x   x
-------------
3   x   x   x
-------------

Aber wenn deine Tabelle Lücken enthält:
.   A   B   C
-------------
1   x   x   x
-------------
2   x   x
-------------
3           x
-------------

Funktioniert die Lösung nicht mehr. Da rutscht z.B. die <td> vom C3 an die stelle von A3.

Man nimm sich am Wo.End immerwas vor und es kommt just anderes ;-) und in der Arbeit habe ich eben zu arbeiten ;-) so dass ich wirklich keine Zeit hatte zum Grübeln.
Dein XSL habe ich nur ein wenig vereinfacht, aber im grunde nichts geändert:

Grüße
Thomas

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="posPerPage" select="3"/>
<xsl:key name="folgenr" match="Table" use="folgenr"/>
<xsl:key name="zuordnung" match="Table" use="zuordnung"/>
<xsl:template match="/">
 <html>
 <head>
  <title>Untitled</title>
 </head>
 <body>
 <xsl:apply-templates  />
 </body>
 </html>
</xsl:template>
<xsl:template match="data">
 <xsl:for-each select="Table[generate-id(.) = generate-id(key('folgenr',folgenr)[1])]">
  <xsl:if test="position() mod $posPerPage = 0 or position() = 1">
   xsl:choose
    <xsl:when test="position() = 1">
     <xsl:call-template name="newTable">
      <xsl:with-param name="start" select="number(position())" />
      <xsl:with-param name="end" select="number(position() + $posPerPage -1 )" />
     </xsl:call-template>
    </xsl:when>
    xsl:otherwise
     <xsl:call-template name="newTable">
      <xsl:with-param name="start" select="number(position() +1)" />
      <xsl:with-param name="end" select="number((position()) +  $posPerPage)" />
     </xsl:call-template>
    </xsl:otherwise>
   </xsl:choose>
  </xsl:if>
 </xsl:for-each>
</xsl:template>
<!-- Template für einzelne Tabellen
  Uebergabeparameter: Start-Position, End-Position -->

<xsl:template name="newTable">
<xsl:param name="start" />
<xsl:param name="end" />
<br/>
Artikel <xsl:value-of select="$start"/> bis <xsl:value-of select="$end"/><br/><br/>
<!-- Link zur nächsten Tabelle -->
<a name="{$start}"></a>
<!-- <a href="#{$end+1}"><font class="h1">Nächste Seite</font></a> -->
<!-- <br/><br/> -->
<!-- Tabelle -->
<table class="h1" cellspacing="0" cellpadding="1" border="1">
 <tr>
  <td valign="bottom">Artikel<br></br>Zuordnung</td><td>Fakt.</td>
  <!-- Artikel -->
  <xsl:for-each select="//Table[generate-id(.) = generate-id(key('folgenr',folgenr)[1])]">
   <xsl:if test="(position() >= $start) and (position() <= $end)">
    <td width="{round(875 div ($posPerPage+1))}px" height="100px" align="center" valign="top"><xsl:value-of select="artikelgruppe"/><br/><br/><xsl:value-of select="artikel"/></td>
   </xsl:if>
  </xsl:for-each>
 </tr>

<!-- Zuordnung und Faktor -->
 <xsl:for-each select="//Table[generate-id(.) = generate-id(key('zuordnung',zuordnung)[1])]">
  <tr>
   <td width="125px" align="left"><xsl:value-of select="substring(zuordnung,1,30)"/></td>
   <td align="center"><xsl:value-of select="faktor"/></td>
  <!-- Multiplikatoren und Mengen pro Zuordnung -->
   <xsl:for-each select="key('zuordnung', zuordnung)">
    <xsl:if test="(position() >= $start) and (position() <= $end)">
     <td>
      <table class="h1" width="100%">
      <tr>
       <td>
        <table class="h1" width="100%" cellspacing="0" cellpadding="0">
         <tr><td align="left"><xsl:value-of select="anzahl"/></td></tr>
        </table>
       </td>
       <td>
        <table class="h1"  width="100%" cellspacing="0" cellpadding="0">
         <tr><td align="right"> <xsl:value-of select="menge"/></td></tr>
        </table>
       </td>
      </tr>
      </table>
     </td>
    </xsl:if>
   </xsl:for-each>
  </tr>
 </xsl:for-each>
 <!-- Gesamtsumme pro Artikel -->
 <tr><td><b>Gesamtsumme</b></td><td align="center"><b>=</b></td>
 <xsl:for-each select="//Table[generate-id(.) = generate-id(key('folgenr',folgenr))]">
  <xsl:if test="(position() >= $start) and (position() <= $end) and (key('folgenr', folgenr)[position() = last()])">
   <td align="right"><b><xsl:value-of select="gesamtmenge"/></b></td>
  </xsl:if>
 </xsl:for-each>
 </tr>
</table>
</xsl:template>
</xsl:stylesheet>