XSLT: multiple tables



我在创建 xslt 文件时遇到了这个小问题......我有这个通用的 xml 文件:

<data>
  <folder>
    <file>
      <name>file1</name>
      <date>2000</date>
      <index1>1</index1>
      <index2>1</index2>
    </file>
    <file>
      <name>file2</name>
      <date>2001</date>
      <index1>1</index1>
      <index2>1</index2>
    </file>
    <file>
      <name>file3</name>
      <date>2004</date>
      <index1>2</index1>
      <index2>1</index2>
    </file>
  </folder>
</data>

给定这个抽象的例子,我必须将其转换为以下内容:

<table>
  <tr>
    <td>Name</td>
    <td>Date</td>
  </tr>
  <tr>
    <td>file1</td>
    <td>2000</td>
  </tr>
  <tr>
    <td>file2</td>
    <td>2001</td>
  </tr>
</table>
<table>
  <tr>
    <td>Name</td>
    <td>Date</td>
  </tr>
  <tr>
    <td>file3</td>
    <td>2004</td>
  </tr>
</table>

我必须根据它们的 index1 和 index2(如 ID 对)对每个表的文件元素进行分组。我能够为每个单独的文件创建一个表,但我无法提供为每个文件共享索引1和索引2创建一个表的解决方案。有什么想法或建议吗?

由于使用的是 XSLT 2.0,因此可以使用 xsl:for-each-group 语句。在这里,您有两种选择,具体取决于您是希望将组保持在一起并遵守顺序,还是只想分组而不考虑顺序。

也就是说,给定aabaab您想要(aaaa, bb)组或(aa, b, aa, b)组?

这首先将所有文件元素分组为具有相同index1index2,无论文档中的顺序如何(我放入body元素只是为了使其格式正确)

<xsl:template match="folder">
    <body>
    <xsl:for-each-group select="file" group-by="concat(index1, '-', index2)">
        <!-- xsl:for-each-group sets the first element in the group as the context node -->
        <xsl:apply-templates select="."/>
    </xsl:for-each-group>
    </body>
</xsl:template>
<xsl:template match="file">
    <table>
        <tr>
            <td>Name</td>
            <td>Date</td>
        </tr>
        <xsl:apply-templates select="current-group()" mode="to-row"/>
    </table>
</xsl:template>
<xsl:template match="file" mode="to-row">
    <tr>
        <xsl:apply-templates select="name|date"/>
    </tr>
</xsl:template>
<xsl:template match="name|date">
    <td><xsl:apply-templates/></td>
</xsl:template>

第二个版本只需要将第一个模板更改为:

<xsl:template match="folder">
    <body>
    <xsl:for-each-group select="file" group-adjacent="concat(index1, '-', index2)">
        <xsl:apply-templates select="."/>
    </xsl:for-each-group>
    </body>
</xsl:template>

最新更新