2011-05-19 45 views
1

我有下面這段XML文件:使用XSLT結構化對象的XML列表轉換成HTML表格多列

<PASS> 
<FIRMWARE Unit="1" Group="FIRM"> 
    <test name="ACPI" ID="ACPI" /> 
</FIRMWARE> 
<NETWORK Unit="2" Group="NTWK"> 
    <test name="Controller Test" ID="Ctlr" /> 
</NETWORK> 
<NETWORK Unit="1" Group="NTWK"> 
    <test name="Controller Test" ID="Ctlr" /> 
</NETWORK> 
<ATA Unit="1" Group="ATA-"> 
    <test name="Serial Controllers" ID="SATA" /> 
</ATA> 
<PARALLEL_PORT Unit="1" Group="LPT-"> 
    <test name="Verify Controller" ID="Ctrl" /> 
    <test name="Check Status Port" ID="Stat" /> 
    <test name="Interrupt Test" ID="Int-" /> 
</PARALLEL_PORT> 
<SERIAL_PORT Unit="4" Group="COM-"> 
    <test name="Interrupt" ID="Intr" /> 
    <test name="Line Control" ID="Line" /> 
    <test name="Test Loopback" ID="LpBk" /> 
    <test name="Test Internal FIFO" ID="FIFO" /> 
    <test name="Test Internal Loopback" ID="ILBk" /> 
</SERIAL_PORT> 
<SERIAL_PORT Unit="3" Group="COM-"> 
    <test name="Interrupt" ID="Intr" /> 
    <test name="Line Control" ID="Line" /> 
    <test name="Test Loopback" ID="LpBk" /> 
    <test name="Test Internal FIFO" ID="FIFO" /> 
    <test name="Test Internal Loopback" ID="ILBk" /> 
</SERIAL_PORT> 
</PASS> 

與現有的XSL文件,我得到了一個列中的所有測試結果。這對印刷等不太實際。我如何創建一個2列或更多列的表格?

<xsl:template match="PASS"> 
<div class="component"> 
    <h4>PASSED</h4> 
    <xsl:call-template name="outputtable"> 
    <xsl:with-param name="result" select="'PASSED'" /> 
    </xsl:call-template> 
</div> 
</xsl:template> 

<xsl:template name="outputtable"> 
<div class="attributes"> 
    <xsl:variable name="resultlist" select="*" /> 
    <xsl:variable name="index" select="count(child::*)" /> 
    <xsl:for-each select="$resultlist"> 
    <xsl:variable name="Unit" select="@Unit" /> 
    <xsl:variable name="Group" select="@Group" /> 
    <p class="attrtitle"> 
     <xsl:value-of select="name()" /> 
     Unit: 
     <xsl:value-of select="$Unit" /> 
    </p> 
    <xsl:variable name="testtype" select="*" /> 
    <xsl:for-each select="$testtype"> 
     <p class="attribute"> 
     <xsl:value-of select="@name" /> 
     </p> 
    </xsl:for-each> 
    <p /> 
    </xsl:for-each> 
</div> 

我已經搜索解決方案,發現以下鏈接: Use xslt to convert xml list into html table with multiple columnshttp://blogs.msdn.com/b/kaevans/archive/2003/04/03/4754.aspx

我的情況是完全不同的我已經結構化的對象,而不是簡單的「項目」或「ComputerName」,另一個缺點是那些測試不是同一類型(等)。這個XML報告是由非OSS軟件自動構建的,因此我無法在創建時更改它。

我會很高興得到任何想法!

+0

你能發佈你想要的輸出嗎? – 2011-05-19 10:59:25

+0

好問題,+1。查看我的答案,獲得完整而簡單的解決方案。還提供了詳細的解釋。學習使用模板而不是'' - 模板更加強大和優雅。 – 2011-05-19 12:34:06

回答

0

該轉化

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

    <xsl:param name="pnumCols" select="3"/> 

    <xsl:template match="PASS"> 
     <div class="component"> 
      <h4>PASSED</h4> 
      <div class="attributes"> 
      <table border="1"> 
       <xsl:apply-templates select= 
        "*[position() mod $pnumCols = 1]"/> 
      </table> 
      </div> 
     </div> 
    </xsl:template> 

    <xsl:template match="PASS/*"> 
    <tr> 
     <xsl:apply-templates mode="process" select= 
     ".|following-sibling::*[not(position() > $pnumCols -1)]"/> 
    </tr> 
    </xsl:template> 

    <xsl:template match="PASS/*" mode="process"> 
    <xsl:variable name="Unit" select="@Unit" /> 
    <xsl:variable name="Group" select="@Group" /> 
    <td> 
     <p class="attrtitle"> 
      <xsl:value-of select="name()" />  Unit: 
      <xsl:value-of select="$Unit" /> 
     </p> 
     <xsl:variable name="testtype" select="*" /> 
     <xsl:for-each select="$testtype"> 
      <p class="attribute"> 
       <xsl:value-of select="@name" /> 
      </p> 
     </xsl:for-each> 
     <p /> 
    </td> 
    </xsl:template> 
</xsl:stylesheet> 

當所提供的XML文檔應用:

<PASS> 
    <FIRMWARE Unit="1" Group="FIRM"> 
     <test name="ACPI" ID="ACPI" /> 
    </FIRMWARE> 
    <NETWORK Unit="2" Group="NTWK"> 
     <test name="Controller Test" ID="Ctlr" /> 
    </NETWORK> 
    <NETWORK Unit="1" Group="NTWK"> 
     <test name="Controller Test" ID="Ctlr" /> 
    </NETWORK> 
    <ATA Unit="1" Group="ATA-"> 
     <test name="Serial Controllers" ID="SATA" /> 
    </ATA> 
    <PARALLEL_PORT Unit="1" Group="LPT-"> 
     <test name="Verify Controller" ID="Ctrl" /> 
     <test name="Check Status Port" ID="Stat" /> 
     <test name="Interrupt Test" ID="Int-" /> 
    </PARALLEL_PORT> 
    <SERIAL_PORT Unit="4" Group="COM-"> 
     <test name="Interrupt" ID="Intr" /> 
     <test name="Line Control" ID="Line" /> 
     <test name="Test Loopback" ID="LpBk" /> 
     <test name="Test Internal FIFO" ID="FIFO" /> 
     <test name="Test Internal Loopback" ID="ILBk" /> 
    </SERIAL_PORT> 
    <SERIAL_PORT Unit="3" Group="COM-"> 
     <test name="Interrupt" ID="Intr" /> 
     <test name="Line Control" ID="Line" /> 
     <test name="Test Loopback" ID="LpBk" /> 
     <test name="Test Internal FIFO" ID="FIFO" /> 
     <test name="Test Internal Loopback" ID="ILBk" /> 
    </SERIAL_PORT> 
</PASS> 

產生在$pnumCols -column格式的結果,在這種具體情況下是pnumCols 3 :

<div class="component"> 
    <h4>PASSED</h4> 
    <div class="attributes"> 
     <table border="1"> 
     <tr> 
      <td> 
       <p class="attrtitle">FIRMWARE  Unit: 
      1</p> 
       <p class="attribute">ACPI</p> 
       <p/> 
      </td> 
      <td> 
       <p class="attrtitle">NETWORK  Unit: 
      2</p> 
       <p class="attribute">Controller Test</p> 
       <p/> 
      </td> 
      <td> 
       <p class="attrtitle">NETWORK  Unit: 
      1</p> 
       <p class="attribute">Controller Test</p> 
       <p/> 
      </td> 
     </tr> 
     <tr> 
      <td> 
       <p class="attrtitle">ATA  Unit: 
      1</p> 
       <p class="attribute">Serial Controllers</p> 
       <p/> 
      </td> 
      <td> 
       <p class="attrtitle">PARALLEL_PORT  Unit: 
      1</p> 
       <p class="attribute">Verify Controller</p> 
       <p class="attribute">Check Status Port</p> 
       <p class="attribute">Interrupt Test</p> 
       <p/> 
      </td> 
      <td> 
       <p class="attrtitle">SERIAL_PORT  Unit: 
      4</p> 
       <p class="attribute">Interrupt</p> 
       <p class="attribute">Line Control</p> 
       <p class="attribute">Test Loopback</p> 
       <p class="attribute">Test Internal FIFO</p> 
       <p class="attribute">Test Internal Loopback</p> 
       <p/> 
      </td> 
     </tr> 
     <tr> 
      <td> 
       <p class="attrtitle">SERIAL_PORT  Unit: 
      3</p> 
       <p class="attribute">Interrupt</p> 
       <p class="attribute">Line Control</p> 
       <p class="attribute">Test Loopback</p> 
       <p class="attribute">Test Internal FIFO</p> 
       <p class="attribute">Test Internal Loopback</p> 
       <p/> 
      </td> 
     </tr> 
     </table> 
    </div> 
</div> 

說明:我們使用兩個模板 - 一個用於包裝一組連續的$pnumCols結果在一排,另外,在mode="process",該行內實際產生的內容。

+0

Dimitre,非常感謝。它像一個魅力! – yegorich 2011-05-19 13:46:22

+0

@yegorich:不客氣。 – 2011-05-19 13:49:12