2011-04-14 160 views
4

我需要能夠將平坦的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> 

回答

4

我發佈了這個問題後很快就試圖解決這個問題,這就是我想出的。我想這會讓你等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

2

該樣式表:

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

的直向前和短溶液

<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

0

我前幾天發表了一篇文章,希望它可以幫助你: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