XSLT:多个表

时间:2013-10-24 19:14:02

标签: xslt

我在创建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对)对每个表的文件元素进行分组。我能够为每个分离的文件创建一个表,但是我不能为每个共享index1和index2的文件创建一个表。有什么想法或建议吗?

1 个答案:

答案 0 :(得分:0)

由于您使用的是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>