具有空白单元格的XSL和XML动态行

时间:2018-08-31 20:54:32

标签: xml xslt xslt-1.0

我是XSL的新手,我正在尝试以以下结构构建表: enter image description here

我正在使用此XML:

<CARS>
    <CAR>
        <CAR_NUM>65</CAR_NUM>
        <DRIVERS>
            <DRIVER>
                <DRIVER_NUM>123</DRIVER_NUM>
                <DRIVER_NAME>STEVE RODGERS</DRIVER_NAME>
            </DRIVER>
        </DRIVERS>
        <STATS>
            <STAT>
                <LAP>1</LAP>
                <TIME>3:21:10</TIME>
            </STAT>
            <STAT>
                <LAP>2</LAP>
                <TIME>3:21:07</TIME>
            </STAT>
        </STATS>
    </CAR>
    <CAR>
        <CAR_NUM>22</CAR_NUM>

        <DRIVERS>
            <DRIVER>
                <DRIVER_NUM>143</DRIVER_NUM>
                <DRIVER_NAME>TONY STARK</DRIVER_NAME>
            </DRIVER>
            <DRIVER>
                <DRIVER_NUM>155</DRIVER_NUM>
                <DRIVER_NAME>JAMES RHODES</DRIVER_NAME>
            </DRIVER>
        </DRIVERS>

        <STATS>
            <STAT>
                <LAP>1</LAP>
                <TIME>3:22:39</TIME>
            </STAT>
            <STAT>
                <LAP>2</LAP>
                <TIME>3:19:17</TIME>
            </STAT>
            <STAT>
                <LAP>3</LAP>
                <TIME>3:15:46</TIME>
            </STAT>
            <STAT>
                <LAP>4</LAP>
                <TIME>3:17:22</TIME>
            </STAT>
        </STATS>
    </CAR>
</CARS>

不可能有比一圈更多的车手。 CAR NUMBER嵌套的表格对我来说很麻烦,因为我不知道如何使用XSL递归生成空白字段(我猜是这样)。

我知道我的第一次尝试还很遥远,但是就在这里...

<table>
    <xsl:for-each select="CARS/CAR">
    <tr>
        <td><xsl:value-of select="CAR_NUM"/>
        </td>
        <xsl:for-each select="DRIVERS/DRIVER">
        <td><xsl:value-of select="DRIVER_NUM"/>
        </td>
        <td><xsl:value-of select="DRIVER_NAME"/>
        </td>
        </xsl:for-each>
        <xsl:for-each select="STATS/STAT">
        <td><xsl:value-of select="LAP"/>
        </td>
        <td><xsl:value-of select="TIME"/>
        </td>
        </xsl:for-each>
        </tr>
        </xsl:for-each>
</table>

此尝试导致:

65123个史蒂夫·罗杰斯1 3:21:10 2 3:21:07

22143托尼·史塔克155詹姆斯·罗德斯1 3:22:39 2 3:19:17 3 3:15:46 4 3:17:22

我无法解释在循环处理中如何创建空单元格和行。

编辑: 研究它,我相信我需要将XML作为层次结构层进行分析:

Tier 1: CAR_NUM
Tier 2: DRIVER_NUM, DRIVER_NAME
Tier 3: LAP, TIME

运行第一条记录后,我需要嵌套一对夫妇:

T1->T2->T3 - End the row, then test for next record in T2 (if found go to T2)
T2->T3 - End the row, then test for next record in T2 (if not found, go T3)
T3

1 个答案:

答案 0 :(得分:0)

正如评论中指出的那样,我不十分了解如何将车手与单圈联系起来,如果这种关系仅仅是所有车手(除了最后一个)只做一圈,而最后一个车手完成所有剩余的一圈,那么您可以实施如下:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

  <xsl:output method="html" indent="yes" version="5" doctype-system="about:legacy-doctype"/>

  <xsl:template match="/">
    <html>
      <head>
        <title>.NET XSLT Fiddle Example</title>
        <style>
            th, td { vertical-align: top }
        </style>
      </head>
      <body>
          <xsl:apply-templates/>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="CARS">
      <table>
          <thead>
              <tr>
                  <th>CAR NUMBER</th>
                  <th>DRIVER NUMBER</th>
                  <th>DRIVER NAME</th>
                  <th>LAP</th>
                  <th>TIME</th>
              </tr>
          </thead>
          <xsl:apply-templates select="CAR"/>
      </table>
  </xsl:template>

  <xsl:template match="CAR">
      <tbody>
          <xsl:apply-templates select="STATS/STAT"/>
      </tbody>
  </xsl:template>

  <xsl:template match="STAT">
      <tr>
          <xsl:call-template name="create-cells"/>
      </tr>
  </xsl:template>

  <xsl:template match="STAT[1]">
      <tr>
          <td rowspan="{count(../STAT)}">
              <xsl:value-of select="ancestor::CAR/CAR_NUM"/>
          </td>
          <xsl:call-template name="create-cells"/>
      </tr>
  </xsl:template>

  <xsl:template name="create-cells">
      <xsl:variable name="pos" select="position()"/>
      <xsl:apply-templates select="ancestor::CAR/DRIVERS/DRIVER[$pos]/*"/>
      <xsl:apply-templates/>      
  </xsl:template>

  <xsl:template match="DRIVER/*">
      <td>
          <xsl:apply-templates/>
      </td>
  </xsl:template>

  <xsl:template match="DRIVER[last()]/*">
      <td rowspan="{count(ancestor::CAR/STATS/STAT) - count(../DRIVER)}">
          <xsl:apply-templates/>
      </td>
  </xsl:template>

  <xsl:template match="LAP | TIME">
      <td>
          <xsl:value-of select="."/>
      </td>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/6qVRKwy上在线

创建的HTML表格看起来很理想。