Announcement

Collapse
No announcement yet.

Dynamische HTML-Formatierung

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

  • Dynamische HTML-Formatierung

    Hallo,

    ich habe mal wieder eine Frage:
    Gegeben ist folgendes XML:
    HTML Code:
    <MYXML>
    	<FORMATTABLE>
    		<BG>#FFFFFF</BG>
    		<FG>#000000</FG>
    	</FORMATTABLE>	
    
    	<ROWSET>
    	 <ROW>
    	  <JAHR>2011</JAHR>
    	  <BEST_NR>XY1234</BEST_NR>
    	  <AENDER_DATUM>11-FEB-09</AENDER_DATUM>
    	 </ROW>
    	</ROWSET> 
    
    	<FORMATTABLE>
    		<BG>#DDDDDD</BG>
    		<FG>#FFFFFF</FG>
    	</FORMATTABLE>
    	
    	<ROWSET>
    	 <ROW>
    	  <JAHR>2012</JAHR>
    	  <BEST_NR>XY3456</BEST_NR>
    	  <AENDER_DATUM>12-FEB-09</AENDER_DATUM>
    	 </ROW>
    	</ROWSET> 	
    </MYXML>
    Dazu habe ich folgenden Stylesheet geschrieben:
    HTML Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method="html" encoding="UTF-8" indent="yes"/>
    <xsl:template match="/">
      <html>
      <body>
      <xsl:apply-templates/>
      </body>
      </html>
    </xsl:template>  
    
      <xsl:template match="ROWSET">
            <table>
              <tbody>
                <xsl:apply-templates select="ROW"/>
              </tbody>
            </table>    
      </xsl:template>
    
       <xsl:template match="ROW">
      <tr>
        <xsl:for-each select="*">
          <td  bgcolor="#DDDDDD" fgcolor="#FFFFFF">
              <xsl:value-of select="."/>
          </td>
        </xsl:for-each>
      </tr> 
    </xsl:template>
    
     <xsl:template match="FORMATTABLE">
           <!-- do nothing -->
     </xsl:template>
    
    </xsl:stylesheet>
    Das Funktioniert auch ganz gut und gibt mir als output
    HTML Code:
    <table>
    <tbody>
    <tr>
    <td bgcolor="#DDDDDD" fgcolor="#FFFFFF">2011</td>
    <td bgcolor="#DDDDDD" fgcolor="#FFFFFF">XY1234</td>
    <td bgcolor="#DDDDDD" fgcolor="#FFFFFF">11-FEB-09</td>
    </tr>
    </tbody>
    </table> 
    <table>
    <tbody>
    <tr>
    <td bgcolor="#DDDDDD" fgcolor="#FFFFFF">2012</td>
    <td bgcolor="#DDDDDD" fgcolor="#FFFFFF">XY3456</td>
    <td bgcolor="#DDDDDD" fgcolor="#FFFFFF">12-FEB-09</td>
    </tr>
    </tbody>
    </table>
    Wie ihr im XSL seht, habe ich die Formatierung für die Farbe hart codiert in <td bgcolor="#DDDDDD" fgcolor="#FFFFFF">. Im XML gibt es vor jedem <ROWSET> ein Block <FORMATTABLE>. Ich möchte nun, dass im Stylesheet die <BG> und <FG> Werte aus dem vorherigem <FORMATTABLE> eingefügt werden, anstatt diese hart zu codieren.

    Alles klar? Ist es möglich?

    Gruß und danke im Voraus

  • #2
    Ein HTML-Attribut fgcolor gibt es nicht, im folgenden Code ist das Prinzip mit Inline-CSS umgesetzt. Die entscheidende Technik ist die Verwendung von {...} (Attribute Value Templates) in Verbindung mit den parent-/preceding-sibling-XPath-Achsen:
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" encoding="UTF-8" indent="yes"/>
    
      <xsl:template match="/">
        <html>
          <head>
            <title>Test</title>
          </head>
          <body>
            <xsl:apply-templates select="//ROWSET"/>
          </body>
        </html>
      </xsl:template>  
    
      <xsl:template match="ROWSET">
        <table>
          <tbody>
            <xsl:apply-templates select="ROW"/>
          </tbody>
        </table>    
      </xsl:template>
    
      <xsl:template match="ROW">
        <tr>
          <xsl:for-each select="*">
            <td style="color: {../../preceding-sibling::FORMATTABLE[1]/FG}; background-color: {../../preceding-sibling::FORMATTABLE[1]/BG}">
              <xsl:value-of select="."/>
            </td>
          </xsl:for-each>
        </tr> 
      </xsl:template>
    
    </xsl:stylesheet>

    Comment


    • #3
      Vielen Dank, das ist super.

      Du hast es mit Inline CSS gelöst. Da kommt mir gleich die Frage:

      Könnte man die CSS definition auslagern? Das heist, zuerst wird im HTML Kopf die CSS-Definitionion für alle <FORMATTABLE> generiert und im <TD> referenziert man auf den richtigen Style?

      Comment


      • #4
        Das lässt sich so lösen (hier entstehen nach der aktuellen Position CSS-Regeln für die Klassenselektoren .stil1 und .stil2 und ihre td-Zuordnung):
        Code:
        <?xml version="1.0" encoding="UTF-8"?>
        <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output method="html" encoding="UTF-8" indent="yes"/>
        
          <xsl:template match="/">
            <html>
              <head>
                <title>Test</title>
                <style type="text/css">
                  <xsl:for-each select="//FORMATTABLE">
                    <xsl:text>&#xA;</xsl:text>
                    <xsl:value-of select="concat('.stil',position())"/>
                    <xsl:text>{</xsl:text>
                    <xsl:value-of select="concat('color: ',FG,';')"/>
                    <xsl:value-of select="concat('background-color: ',BG,';')"/>
                    <xsl:text>}</xsl:text>
                  </xsl:for-each>        
                  <xsl:text>&#xA;</xsl:text>
                </style>
              </head>
              <body>
                <xsl:apply-templates select="//ROWSET"/>
              </body>
            </html>
          </xsl:template>  
        
          <xsl:template match="ROWSET">
            <table>
              <tbody>
                <xsl:apply-templates select="ROW"/>
              </tbody>
            </table>    
          </xsl:template>
        
          <xsl:template match="ROW">
            <tr>
              <xsl:for-each select="*">
                <td class="stil{count(../../preceding-sibling::ROWSET) + 1}">
                  <xsl:value-of select="."/>
                </td>
              </xsl:for-each>
            </tr> 
          </xsl:template>
        
        </xsl:stylesheet>
        Statt mehrfacher Klassenzuweisung bzgl. td-Elementen kann die jeweilige Klasse auch dem übergeordneten tr-Element zugeordnet werden:

        Code:
          <xsl:template match="ROW">
            <tr class="stil{count(../preceding-sibling::ROWSET) + 1}">
              <xsl:for-each select="*">
                <td>
                  <xsl:value-of select="."/>
                </td>
              </xsl:for-each>
            </tr> 
          </xsl:template>

        Comment

        Working...
        X