使用 xslt 将结构化对象的 xml 列表转换为包含多列的 html 表



我有以下一段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>

使用现有的 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>

我已经搜索了解决方案并找到了以下链接:使用 xslt 将 xml 列表转换为包含多列的 html 表,并且http://blogs.msdn.com/b/kaevans/archive/2003/04/03/4754.aspx

的情况相当不同,我有结构化的对象,不像"项目"或"计算机名"那样简单,另一个缺点是这些测试不属于同一类型(等)。此XML报告是由非OSS软件自动构建的,因此我在创建时无法更改它。

我很乐意得到任何想法!

此转换

<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 列格式生成结果,在此特定情况下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",以实际生成该行中的内容。

最新更新