XSLT和动态表列

时间:2010-08-23 20:50:42

标签: xslt

我开发了一个XSL文件,可以将xml文件转换为html表。我们的想法是只有一个xsl文件将许多xml文件转换为html表,而不是10个xml文件和10个附带的xsl文件。我已经包含了一个xsl文件和2个xml文件,它们使用xsl文件将它们转换为html表。我遇到的问题是我似乎无法弄清楚如何创建行的列来完成生成的表。请测试下面的代码以获得理解。欢迎所有支持。谢谢!

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>

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>

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>

更新

这是一个xsl文件,它将格式化我提供的test_xml1.xml文件。尝试将此xsl文件与test_xml2.xml文件一起使用时,您会注意到该表出现时缺少列。原因是因为它是硬编码的。理想情况下,这应该是动态的。希望我很清楚。谢谢你的帮助!

<?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>

1 个答案:

答案 0 :(得分:1)

列没有数据,标题和实际行之间没有关系,但这会生成正确数量的(空)单元格...

<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>

基本上,不是对单元格进行硬编码,而是通过第一级标题循环以获得正确数量的单元格。在上面的示例代码中,我正在跳过第一个单元格(position()&gt; 1),因为您已经在输出它。