使用XSLT将XML转换为HTML表

问题描述:

我需要能够将平坦的xml数据集转换为html表格,并且无法找到适合我需要的语法示例。我想使用一个样式表,可以将类似的外观数据集转换为具有可变列的html表格。这意味着除了“行”和“行”之外,它不能使用任何硬编码的元素名称。使用XSLT将XML转换为HTML表

后,我的样式表将能够转换:

<?xml version="1.0" encoding="UTF-8"?> 
<rows> 
    <row> 
    <AccountId>BlPUAA0</AccountId> 
    <AccountName>Initech</AccountName> 
    <AcocuntStatus>Client</AcocuntStatus> 
    </row> 
    <row> 
    <AccountId>CJxIAAW</AccountId> 
    <AccountName>Intertrode</AccountName> 
    <AcocuntStatus>Prospect</AcocuntStatus> 
    </row> 
</rows> 

到:

<table> 
    <tr> 
    <th>AccountId</th> 
    <th>AccountName</th> 
    <th>AcocuntStatus</th> 
    </tr> 
    <tr> 
    <td>BlPUAA0</td> 
    <td>Initech</td> 
    <td>Client</td> 
    </tr> 
    <tr> 
    <td>CJxIAAW</td> 
    <td>Intertrode</td> 
    <td>Client</td> 
    </tr> 
</table> 

这:

<?xml version="1.0" encoding="UTF-8"?> 
<rows> 
    <row> 
    <AccountId>BlPUAA0</AccountId> 
    <AccountName>Initech</AccountName> 
    </row> 
    <row> 
    <AccountId>CJxIAAW</AccountId> 
    <AccountName>Intertrode</AccountName> 
    </row> 
</rows> 

到这一点:

<table> 
    <tr> 
    <th>AccountId</th> 
    <th>AccountName</th> 
    </tr> 
    <tr> 
    <td>BlPUAA0</td> 
    <td>Initech</td> 
    </tr> 
    <tr> 
    <td>CJxIAAW</td> 
    <td>Intertrode</td> 
    </tr> 
</table> 

我发布了这个问题后很快就试图解决这个问题,这就是我想出的。我想这会让你等24小时后才能自己回答。

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/> 
    <xsl:template match="/"> 
    <table> 
     <tr> 
     <xsl:for-each select="rows/row[1]/*"> 
      <th> 
      <xsl:value-of select ="local-name()"/> 
      </th> 
     </xsl:for-each> 
     </tr> 
     <xsl:for-each select="rows/row"> 
     <tr> 
      <xsl:for-each select="*"> 
      <td> 
       <xsl:value-of select="."/> 
      </td> 
      </xsl:for-each> 
     </tr> 
     </xsl:for-each> 
    </table> 
    </xsl:template> 
</xsl:stylesheet> 
+0

一定要向别人学习答案。这种模板“砖”不是很有用。 – 2011-04-16 05:37:39

该样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="/"> 
     <table> 
      <xsl:apply-templates select="rows/row[1]" /> 
     </table> 
    </xsl:template> 
    <xsl:template match="row"> 
     <tr> 
      <xsl:apply-templates mode="th" /> 
     </tr> 
     <xsl:apply-templates select="../row" mode="td" /> 
    </xsl:template> 
    <xsl:template match="row/*" mode="th"> 
     <th> 
      <xsl:value-of select="local-name()" /> 
     </th> 
    </xsl:template> 
    <xsl:template match="row" mode="td"> 
     <tr> 
      <xsl:apply-templates /> 
     </tr> 
    </xsl:template> 
    <xsl:template match="row/*"> 
     <td> 
      <xsl:apply-templates /> 
     </td> 
    </xsl:template> 
</xsl:stylesheet> 

应用于:

<rows> 
    <row> 
     <AccountId>BlPUAA0</AccountId> 
     <AccountName>Initech</AccountName> 
     <AcocuntStatus>Client</AcocuntStatus> 
    </row> 
    <row> 
     <AccountId>CJxIAAW</AccountId> 
     <AccountName>Intertrode</AccountName> 
     <AcocuntStatus>Prospect</AcocuntStatus> 
    </row> 
</rows> 

产地:

<table> 
    <tr> 
     <th>AccountId</th> 
     <th>AccountName</th> 
     <th>AcocuntStatus</th> 
    </tr> 
    <tr> 
     <td>BlPUAA0</td> 
     <td>Initech</td> 
     <td>Client</td> 
    </tr> 
    <tr> 
     <td>CJxIAAW</td> 
     <td>Intertrode</td> 
     <td>Prospect</td> 
    </tr> 
</table> 

并应用于:

<rows> 
    <row> 
    <AccountId>BlPUAA0</AccountId> 
    <AccountName>Initech</AccountName> 
    </row> 
    <row> 
    <AccountId>CJxIAAW</AccountId> 
    <AccountName>Intertrode</AccountName> 
    </row> 
</rows> 

产地:

<table> 
    <tr> 
     <th>AccountId</th> 
     <th>AccountName</th> 
    </tr> 
    <tr> 
     <td>BlPUAA0</td> 
     <td>Initech</td> 
    </tr> 
    <tr> 
     <td>CJxIAAW</td> 
     <td>Intertrode</td> 
    </tr> 
</table> 

或者,该样式表生成使用条件和少一个模板相同的输出:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="/"> 
     <table> 
      <xsl:apply-templates select="rows/row" /> 
     </table> 
    </xsl:template> 
    <xsl:template match="row"> 
     <xsl:if test="position()=1"> 
      <tr> 
       <xsl:apply-templates mode="th" /> 
      </tr> 
     </xsl:if> 
     <tr> 
      <xsl:apply-templates /> 
     </tr> 
    </xsl:template> 
    <xsl:template match="row/*" mode="th"> 
     <th> 
      <xsl:value-of select="local-name()" /> 
     </th> 
    </xsl:template> 
    <xsl:template match="row/*"> 
     <td> 
      <xsl:apply-templates /> 
     </td> 
    </xsl:template> 
</xsl:stylesheet> 

的直向前和短溶液

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="/*"> 
    <table><xsl:apply-templates select="row"/></table> 
</xsl:template> 

<xsl:template match="row[1]"> 
    <tr><xsl:apply-templates select="*" mode="header"/></tr> 
    <xsl:call-template name="standardRow"/> 
</xsl:template> 

<xsl:template match="row" name="standardRow"> 
    <tr><xsl:apply-templates select="*"/></tr> 
</xsl:template> 

<xsl:template match="row/*"> 
    <td><xsl:apply-templates select="node()"/></td> 
</xsl:template> 

<xsl:template match="row/*" mode="header"> 
    <th><xsl:value-of select="name()"/></th> 
</xsl:template> 
</xsl:stylesheet> 

施加时在第一次提供的XML文件

<rows> 
    <row> 
     <AccountId>BlPUAA0</AccountId> 
     <AccountName>Initech</AccountName> 
     <AcocuntStatus>Client</AcocuntStatus> 
    </row> 
    <row> 
     <AccountId>CJxIAAW</AccountId> 
     <AccountName>Intertrode</AccountName> 
     <AcocuntStatus>Prospect</AcocuntStatus> 
    </row> 
</rows> 

有用,正确的结果产生:

<table> 
    <tr> 
     <th>AccountId</th> 
     <th>AccountName</th> 
     <th>AcocuntStatus</th> 
    </tr> 
    <tr> 
     <td>BlPUAA0</td> 
     <td>Initech</td> 
     <td>Client</td> 
    </tr> 
    <tr> 
     <td>CJxIAAW</td> 
     <td>Intertrode</td> 
     <td>Prospect</td> 
    </tr> 
</table> 

当在第二提供的XML文档应用:

<rows> 
    <row> 
     <AccountId>BlPUAA0</AccountId> 
     <AccountName>Initech</AccountName> 
    </row> 
    <row> 
     <AccountId>CJxIAAW</AccountId> 
     <AccountName>Intertrode</AccountName> 
    </row> 
</rows> 

再次期望的,正确的结果产生:

<table> 
    <tr> 
     <th>AccountId</th> 
     <th>AccountName</th> 
    </tr> 
    <tr> 
     <td>BlPUAA0</td> 
     <td>Initech</td> 
    </tr> 
    <tr> 
     <td>CJxIAAW</td> 
     <td>Intertrode</td> 
    </tr> 
</table> 
+0

+1 normalizated表很好的回答。如果没有这些不必要的“选择”,这将更加清晰的拉式风格的方法。 – 2011-04-14 16:38:56

我前几天发表了一篇文章,希望它可以帮助你:http://web.swfideas.com/?p=12191

Asuming这样的数据:现在

<?xml version="1.0" encoding="UTF-8"?> 
<!-- Edited by XMLSpy --> 
<table-node> 
    <tbody> 
    <tr> 
     <td>[C1R1]</td> 
     <td>[C2R1]</td> 
    </tr> 
    <tr> 
     <td>[C1R2]</td> 
     <td>[C2R2]</td> 
    </tr> 
    <tr> 
     <td>[C1R3]</td> 
     <td>[C2R3]</td> 
    </tr> 
    </tbody> 
</table-node> 

,核心,我们的XSLT模板:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<!-- Coded by SWFideas --> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<!-- table template --> 
<xsl:template match="table-node"> 
    <table style="border:solid #000000 1px;border-spacing: 0;border-collapse: collapse;"> 
     <xsl:for-each select="tbody"> 
      <tbody> 
       <xsl:for-each select="tr"> 
        <tr> 
         <xsl:for-each select="td"> 
          <td style="border:solid #000000 1px; padding: 5px;"> 
           <xsl:value-of select="."/> 
          </td> 
         </xsl:for-each>      
        </tr>     
       </xsl:for-each> 
      </tbody> 
     </xsl:for-each> 
    <table> 
</xsl:template> 
</xsl:stylesheet> 

在这个第一种方法中,我避免使用COLSPAN和另一个真实的属性(即将实施,我承诺)。因此,如果结果,我们运用我们的XSLT会是这样:

<table style="border:solid #000000 1px;border-spacing: 0;border-collapse: collapse;"> 
    <tbody> 
     <tr> 
      <td style="border:solid #000000 1px; padding: 5px;">[C1R1]</td> 
      <td style="border:solid #000000 1px; padding: 5px;">[C2R1]</td> 
     </tr> 
     <tr> 
      <td style="border:solid #000000 1px; padding: 5px;">[C1R2]</td> 
      <td style="border:solid #000000 1px; padding: 5px;">[C2R2]</td> 
     </tr> 
     <tr> 
      <td style="border:solid #000000 1px; padding: 5px;">[C1R3]</td> 
      <td style="border:solid #000000 1px; padding: 5px;">[C2R3]</td> 
     </tr> 
    </tbody> 
</table> 

你可以在这里尝试一下:http://www.xsltcake.com/slices/gNfh6i/2