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

发布于 2024-11-08 06:43:56 字数 2936 浏览 1 评论 0原文

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

我的情况相当不同,我有结构化对象,而不是像“Item”或“ComputerName”的另一个缺点是这些测试不是同一类型(等等)。该 XML 报告是由非 OSS 软件自动构建的,因此我无法在创建时更改它。

我很高兴得到任何想法!

I have following piece of XML file:

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

With the existing XSL file I get all test results in one column. This is not very practical for printing and so on. How can I create a table with 2 or more columns?

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

I've already searched for solution and found following links:
Use xslt to convert xml list into html table with multiple columns and
http://blogs.msdn.com/b/kaevans/archive/2003/04/03/4754.aspx

The situation I have is rather different I have structured objects and not simple as "Item" or "ComputerName" and the other drawback is that those test are not of the same type (, etc.). This XML report is constructed automatically by non-OSS software, so I have no way to change it at creation time.

I'll be glad to get any ideas!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

╄→承喏 2024-11-15 06:43:56

此转换

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

This transformation:

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

when applied on the provided XML document:

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

produces the results in $pnumCols-column format, in this specific case pnumCols is 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>

Explanation: We use two templates -- one for wrapping a group of $pnumCols consecutive results in a row, the other, in mode="process", to actually produce the contents within that row.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文