Announcement

Collapse
No announcement yet.

XSL Tabellenaufbau mit Array

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

  • XSL Tabellenaufbau mit Array

    Hallo Ihrs

    Die Überschrift trifft vllt nict so ganz mein Problem (wusste aber nicht wie ich es so kurz Umschreiben soll).
    Na hauptsache ihr versteht was ich meine wenn ich es etwas ausführlicher schildere.

    Ich habe folgende XML Baumstruktur:

    HTML Code:
    -
    <menue nr="0">
    <portal>name001</portal>
    <language>DE</language>
    </menue><menue nr="1">
    <portal>name001</portal>
    <language>EN</language>
    </menue><menue nr="2">
    <portal>name001</portal>
    <language>SP</language>
    </menue><menue nr="4">
    <portal>name001</portal>
    <language>NL</language>
    </menue><menue nr="5">
    <portal>name002</portal>
    <language>DE</language>
    </menue><menue nr="6">
    <portal>name002</portal>
    <language>DK</language>
    </menue><menue nr="7">
    <portal>name002</portal>
    <language>EN</language>
    </menue><menue nr="8">
    <portal>name002</portal>
    <language>NL</language>
    </menue><menue nr="9">
    <portal>name002</portal>
    <language>SP</language>
    </menue>
    -
    <menue nr="11">
    <portal>name003</portal>
    <language>DE</language>
    </menue><menue nr="12">
    <portal>name003</portal>
    <language>EN</language>
    </menue>
    Hierraus möchte ich nun eine geordnete Tabelle ähnlich
    ---------------DE--EN--SP--NL--DK
    name001----x----x----x
    name002----x----x----x----x----x
    name003----x--- x

    in XSL erstellen.

    Ich habe nun mehrere Ansätze versucht und bin gescheitert.

    Zum einen habe ich nach dem for-each mit
    <xsl:if test="not(preceding-sibling::menue/portal = portal)">
    die Portal-Parameter (name001, name002 usw) ähnlich der PHP-Funktion array_unique(); zusammengefügt, was gut klappt.
    Allerdings wird mir bei dieser Methode auch nur noch der jeweils letzte Parameter von 'language' angezeigt.

    Meine Frage nun, geht so etwas was ich vorhabe mit XSL überhaupt, oder muss ich alles in PHP schreiben und nur noch einzelne Parameter an mein XSL übergeben.

    Ich hoffe ihr versteht mein Kauderwelch.

    Im Vorraus danke Mad

  • #2
    Mit XSLT 1.0 kann man das per "Muenchian grouping" (http://www.jenitennison.com/xslt/grouping/index.xml) lösen:
    Code:
    <xsl:stylesheet
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      version="1.0">
      
      <xsl:output indent="yes"/>
      
      <xsl:variable name="languages" select="//menue/language"/>
      
      <xsl:key name="k1" match="menue/language" use="."/>
      
      <xsl:key name="k2" match="menue/portal" use="."/>
      
      <xsl:key name="k3" match="menue" use="concat(portal, '|', language)"/>
      
      <xsl:template match="/">
        <html>
          <head>
            <title>Beispiel</title>
          </head>
          <body>
            <xsl:apply-templates/>
          </body>
        </html>
      </xsl:template>
      
      <xsl:template match="root">
        <table frame="box" rules="all">
          <thead>
            <tr>
              <th>Namen</th>
              <xsl:apply-templates select="$languages[generate-id() = generate-id(key('k1', .)[1])]"/>
            </tr>
          </thead>
          <tbody>
            <xsl:apply-templates select="menue/portal[generate-id() = generate-id(key('k2', .)[1])]"/>
          </tbody>
        </table>
      </xsl:template>
      
      <xsl:template match="menue/language">
        <th><xsl:value-of select="."/></th>
      </xsl:template>
      
      <xsl:template match="menue/portal">
        <tr>
          <td><xsl:value-of select="."/></td>
          <xsl:variable name="this-portal" select="."/>
          <xsl:for-each select="$languages[generate-id() = generate-id(key('k1', .)[1])]">
            <td>
              <xsl:choose>
                <xsl:when test="key('k3', concat($this-portal, '|', .))">
                  <xsl:text>x</xsl:text>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:text>&#160;</xsl:text>
                </xsl:otherwise>
              </xsl:choose>
            </td>
          </xsl:for-each>
        </tr>
      </xsl:template>
      
    </xsl:stylesheet>
    Unter der Annahme des Eingabedokumentes
    Code:
    <root>
    
    <menue nr="0">
    <portal>name001</portal>
    <language>DE</language>
    </menue>
    
    <menue nr="1">
    <portal>name001</portal>
    <language>EN</language>
    </menue>
    
    <menue nr="2">
    <portal>name001</portal>
    <language>SP</language>
    </menue>
    
    <menue nr="4">
    <portal>name001</portal>
    <language>NL</language>
    </menue>
    
    <menue nr="5">
    <portal>name002</portal>
    <language>DE</language>
    </menue>
    
    <menue nr="6">
    <portal>name002</portal>
    <language>DK</language>
    </menue>
    
    <menue nr="7">
    <portal>name002</portal>
    <language>EN</language>
    </menue>
    
    <menue nr="8">
    <portal>name002</portal>
    <language>NL</language>
    </menue>
    
    <menue nr="9">
    <portal>name002</portal>
    <language>SP</language>
    </menue>
    
    <menue nr="11">
    <portal>name003</portal>
    <language>DE</language>
    </menue>
    
    <menue nr="12">
    <portal>name003</portal>
    <language>EN</language>
    </menue>
    
    </root>
    kommt dann folgendes Resultat heraus:
    Code:
    <html>
       <head>
          <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    
          <title>Beispiel</title>
       </head>
       <body>
          <table frame="box" rules="all">
             <thead>
                <tr>
                   <th>Namen</th>
                   <th>DE</th>
                   <th>EN</th>
                   <th>SP</th>
                   <th>NL</th>
                   <th>DK</th>
                </tr>
             </thead>
             <tbody>
                <tr>
                   <td>name001</td>
                   <td>x</td>
                   <td>x</td>
                   <td>x</td>
                   <td>x</td>
                   <td>&nbsp;</td>
                </tr>
                <tr>
                   <td>name002</td>
                   <td>x</td>
                   <td>x</td>
                   <td>x</td>
                   <td>x</td>
                   <td>x</td>
                </tr>
                <tr>
                   <td>name003</td>
                   <td>x</td>
                   <td>x</td>
                   <td>&nbsp;</td>
                   <td>&nbsp;</td>
                   <td>&nbsp;</td>
                </tr>
             </tbody>
          </table>
       </body>
    </html>
    Mit XSLT 2.0 sollte sich das auch weniger kryptisch mit Hilfe von for-each-group und/oder distinct-values lösen lassen.

    Comment


    • #3
      eine ähnliche lösung

      Code:
      <?xml version="1.0"?>
      <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      	<xsl:output indent="yes" method="html"/>
      	<xsl:key name="portalonly" match="//portal" use="."/>
      	<xsl:variable name="alllanguage" select="//menue/language"/>
      	<xsl:key name="languageonly" match="//menue/language" use="."/>
      	<xsl:template match="/">
      		<html>
      			<style>
      			table { border: 2px solid black; }
      			td,th { border: 2px solid black;
       					text-align: center;}
      			</style>
      			<xsl:apply-templates select="root"/>
      		</html>
      	</xsl:template>
      	<xsl:template match="root">
      		<table>
      			<tr>
      				<th>portal</th>
      				<xsl:apply-templates select="$alllanguage[generate-id() = generate-id(key('languageonly', .)[1])]" mode="menue">
      					<xsl:sort select="."/>
      				</xsl:apply-templates>
      			</tr>
      			<xsl:apply-templates select="menue"/>
      		</table>
      	</xsl:template>
      	<xsl:template match="menue">
      		<xsl:for-each select="portal[generate-id() = generate-id(key('portalonly', .)[1])]">
      			<xsl:variable name="ak" select="."/>
      			<tr>
      				<td>
      					<xsl:value-of select="."/>
      				</td>
      				<xsl:call-template name="all">
      					<xsl:with-param name="all" select="../..//language[../portal=$ak]"/>
      				</xsl:call-template>
      			</tr>
      		</xsl:for-each>
      	</xsl:template>
      	<xsl:template match="language" name="all">
      		<xsl:param name="all"/>
      		<xsl:for-each select="$alllanguage[generate-id() = generate-id(key('languageonly', .)[1])]">
      			<xsl:sort select="."/>
      			<xsl:variable name="ak" select="."/>
      			<xsl:choose>
      				<xsl:when test="$all[.=$ak]">
      					<td>
      						<xsl:text>x</xsl:text>
      					</td>
      				</xsl:when>
      				<xsl:otherwise>
      					<td>
      						<xsl:text>-</xsl:text>
      					</td>
      				</xsl:otherwise>
      			</xsl:choose>
      		</xsl:for-each>
      	</xsl:template>
      	<xsl:template match="language" mode="menue">
      		<th>
      			<xsl:value-of select="."/>
      		</th>
      	</xsl:template>
      </xsl:stylesheet>

      Comment

      Working...
      X