2010-08-23 8 views
1

J'ai développé un fichier XSL qui transforme des fichiers xml en une table html. L'idée est de n'avoir qu'un seul fichier xsl pour transformer de nombreux fichiers xml en une table html, au lieu d'avoir 10 fichiers xml avec 10 fichiers xsl associés. J'ai inclus le fichier xsl et 2 fichiers xml qui utilise le fichier xsl pour les transformer en tables html. Le problème que j'ai est que je n'arrive pas à comprendre comment les colonnes pour les lignes sont créées pour compléter la table générée. S'il vous plaît avoir tester le code ci-dessous pour obtenir une compréhension. Tout le soutien est le bienvenu. Merci!XSLT et colonnes de table dynamiques

ton

fichier XSL: test_xsl.xsl

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="html" indent="yes"/> 

<xsl:template match="/root/sheet"> 
    <html> 
     <head></head> 
     <body> 
      <table border="1" width="100%" cellpadding="0" cellspacing="0" height="100%"> 

       <xsl:apply-templates select="headers"/> 

       <xsl:for-each select="rows"> 
        <xsl:for-each select="item"> 
         <tr> 
          <td> 
           <table border="1" width="100%" height="100%" cellpadding="0" cellspacing="0"> 
            <tr> 
             <td> 
              <b><xsl:value-of select="name" disable-output-escaping="yes" /></b> 
             </td> 

            </tr> 
           </table> 
          </td> 
         </tr> 
        </xsl:for-each> 
       </xsl:for-each> 
      </table> 
     </body> 
    </html> 
</xsl:template> 
<xsl:template match="headers"> 
    <tr> 
     <xsl:apply-templates select="item"/> 
    </tr> 
</xsl:template> 
<xsl:template match="headers//item"> 
    <th> 
     <xsl:choose> 
      <xsl:when test="item"> 
       <table border="1" width="100%" height="100%"> 
        <tr><td colspan="{count(item)}"><xsl:value-of select="name"/></td></tr> 
        <xsl:apply-templates select="item"/> 
       </table> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:value-of select="name"/> 
      </xsl:otherwise> 
     </xsl:choose> 
    </th> 
</xsl:template> 
</xsl:stylesheet> 

fichier XML 1: test_xml1.xml

<?xml version="1.0" encoding="ISO-8859-1"?> 
<?xml-stylesheet type="text/xsl" href="test_xsl.xsl"?> 

<root> 
    <sheet> 
     <titles> 
      <item> 
       <name><![CDATA[Title 1]]></name> 
      </item> 
      <item> 
       <name><![CDATA[Title 2]]></name> 
      </item> 
      <item> 
       <name><![CDATA[Title 3]]></name> 
      </item> 
     </titles> 
     <headers> 
      <item> 
       <name><![CDATA[Header 1]]></name> 
      </item> 
      <item> 
       <name><![CDATA[Header 2]]></name> 
       <item> 
        <name><![CDATA[Sub header 1 of Header 2]]></name> 
       </item> 
       <item> 
        <name><![CDATA[Sub header 2 of Header 2]]></name> 
        <item> 
         <name><![CDATA[Sub header 1 of Sub header 2 of Header 2]]></name> 
        </item> 
        <item> 
         <name><![CDATA[Sub header 2 of Sub header 2 of Header 2]]></name> 
        </item> 
       </item> 
      </item> 
      <item> 
       <name><![CDATA[Header 3]]></name> 
      </item> 
     </headers> 
     <rows> 
      <item> 
       <name><![CDATA[Row 1]]></name> 
      </item> 
      <item> 
       <name><![CDATA[Row 2]]></name> 
      </item> 
      <item> 
       <name><![CDATA[Row 3]]></name> 
      </item> 
      <item> 
       <name><![CDATA[Row 4]]></name> 
      </item> 
     </rows> 
    </sheet> 
</root> 

fichier XML 2: test_xml2.xml

<?xml version="1.0" encoding="ISO-8859-1"?> 
<?xml-stylesheet type="text/xsl" href="test_xsl.xsl"?> 
<root> 
<sheet> 
    <titles> 
    <item> 
    <name><![CDATA[Title 1]]></name> 
    </item> 

    <item> 
    <name><![CDATA[Title 2]]></name> 
    </item> 

    <item> 
    <name><![CDATA[Title 3]]></name> 
    </item> 
    </titles> 
    <headers> 
    <item> 
    <name><![CDATA[Header 1]]></name> 
    </item> 

    <item> 
    <name><![CDATA[Header 2]]></name> 
    </item> 

    <item> 
    <name><![CDATA[Header 3]]></name> 
    </item> 
    <item> 
    <name><![CDATA[Header 4]]></name> 

    <item> 
    <name><![CDATA[Sub header 1 of Header 4]]></name> 
    </item> 

    <item> 
    <name><![CDATA[Sub header 2 of Header 4]]></name> 
    </item> 
    </item> 
    </headers> 

    <rows> 
    <item> 
    <name><![CDATA[Row 1]]></name> 
    </item> 
    <item> 
    <name><![CDATA[Row 2]]></name> 
    </item>       

    <item> 
    <name><![CDATA[Row 3]]></name> 
    </item>       

    <item> 
    <name><![CDATA[Row 4]]></name> 
    </item> 


    </rows> 
</sheet> 
</root> 

MISE À JOUR

Voici un fichier xsl qui formatera le fichier test_xml1.xml que j'ai fourni. Lorsque vous essayez d'utiliser ce fichier xsl avec le fichier test_xml2.xml, vous remarquerez que la table apparaît avec une colonne manquante. La raison en est que c'est codé en dur. Idéalement, cela devrait être dynamique. J'espère que j'étais clair. Merci de votre aide!

<?xml version="1.0" encoding="ISO-8859-1"?> 

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="html" indent="yes"/> 

<xsl:template match="/root/sheet"> 
    <html> 
     <head></head> 
     <body> 
      <table border="1" width="100%" cellpadding="0" cellspacing="0" height="100%"> 
       <xsl:apply-templates select="headers"/> 
       <xsl:for-each select="rows"> 
        <xsl:for-each select="item"> 
         <tr> 
          <td> 
           <table border="1" width="100%" height="100%" cellpadding="0" cellspacing="0"> 
            <tr> 
             <td> 
              <b><xsl:value-of select="name" disable-output-escaping="yes" /></b> 
             </td> 

            </tr> 
           </table> 
          </td> 
          <td><br /></td> 
          <td><br /></td> 
         </tr> 
        </xsl:for-each> 
       </xsl:for-each> 
      </table> 
     </body> 
    </html> 
</xsl:template> 
<xsl:template match="headers"> 
    <tr> 
     <xsl:apply-templates select="item"/> 
    </tr> 
</xsl:template> 
<xsl:template match="headers//item"> 
    <th> 
     <xsl:choose> 
      <xsl:when test="item"> 
       <table border="1" width="100%" height="100%"> 
        <tr><td colspan="{count(item)}" width="40%"><xsl:value-of select="name"/></td></tr> 
        <xsl:apply-templates select="item"/> 
       </table> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:value-of select="name"/> 
      </xsl:otherwise> 
     </xsl:choose> 
    </th> 
</xsl:template> 

+0

Vos données XML sont-elles bloquées dans ce format ou pouvez-vous les modifier? Je peux suggérer de meilleures façons de convertir aux tables HTML. – Starkey

+0

Oui, il est coincé de cette façon mais je suis ouvert à toutes suggestions. – toneb

+0

Dans vos fichiers xml, il n'y a pas de données pour le contenu réel des lignes. S'il vous plaît, fournissez un fichier xml qui contient vraiment ces données. –

Répondre

1

Il n'y a pas de données pour les colonnes et il n'y a pas de relation entre les en-têtes et les lignes réelles, mais cela produira le bon nombre de cellules (vide) ...

<xsl:template match="/root/sheet"> 
    <html> 
     <head></head> 
     <body> 
     <table border="1" width="100%" cellpadding="0" cellspacing="0" height="100%"> 
      <xsl:apply-templates select="headers"/> 
      <xsl:for-each select="rows"> 
      <xsl:for-each select="item"> 
       <tr> 
       <td> 
        <xsl:value-of select="name" disable-output-escaping="yes" /> 
       </td> 
       <!-- 
       <td> 
        <br /> 
       </td> 
       <td> 
        <br /> 
       </td>--> 
       <!-- Loop through all the first level headers except the first one --> 
       <xsl:for-each select="//headers/item[position() &gt; 1]"> 
        <td> 
        <br /> 
        </td> 
       </xsl:for-each> 
       </tr> 
      </xsl:for-each> 
      </xsl:for-each> 
     </table> 
     </body> 
    </html> 
    </xsl:template> 

Fondamentalement, au lieu de coder les cellules en dur, il vous suffit de boucler les en-têtes de premier niveau pour obtenir le bon nombre de cellules. Et dans l'exemple de code ci-dessus, je suis en train de sauter la première cellule (position()> 1) comme vous le produisez déjà.

+0

Merci beaucoup Catch22, vous l'avez cloué. Fonctionne parfaitement! Hey question rapide si cela ne vous dérange pas. Comment puis-je faire en sorte que la première largeur d'en-tête/colonne soit toujours de 40%? Et cela ne semble pas fonctionner correctement dans Firefox, avez-vous ce problème aussi? Encore une fois merci, vous êtes arrivé à la 11ème heure! ton – toneb

+0

Hmmm - Je viens d'ajouter l'attribut: width = "40%" au premier et cela a bien fonctionné dans IE et FireFox. Évidemment, il vaudrait mieux garder le style dans le CSS. Cela fonctionne également: HTML: et CSS dans l'en-tête: Catch22