通过匹配属性对节点进行分组

时间:2014-06-30 06:13:19

标签: xslt

我的输入xml看起来如下所示, 我需要根据id属性对标记进行分组。 即使标记的id属性在下一行中相同,也应该在前一个标记下进行分组。

<Layouts>
<Layout id="1">
<Structure id="2000">
<Row id="1">
<Col id="125"/>
</Row>
<Row id="2">
<Col id="126"/>
</Row>
<Row id="3">
<Col id="125"/>
</Row>
</Structure>
</Layout>

<Layout id="2">
<Structure id="3000">
<Row id="1">
<Col id="125"/>
</Row>
<Row id="2">
<Col id="226"/>
</Row>
<Row id="3">
<Col id="226"/>
</Row>
<Row id="4">
<Col id="125"/>
</Row>
</Structure>
</Layout>
</Layouts>

我的输出xml应该如下所示,

<Layouts>
<Layout id="1">
<Structure id="2000">
<Row id="1">
<Col id="125"/>
<Col id="125"/>
</Row>
<Row id="2">
<Col id="126"/>
</Row>          
</Structure>
</Layout>

<Layout id="2">
<Structure id="3000">
<Row id="1">
<Col id="125"/>
<Col id="125"/>
</Row>
<Row id="2">
<Col id="226"/>
<Col id="226"/>
</Row>          
</Structure>
</Layout>
</Layouts>

正如我们所看到的,每一行应该用相似的id属性值分组,最后它应该显示在一个单独的属性值中。 这种分组应该只针对每个部分进行。 对于每个节点,类似的id应该在节点内分组。 我尝试了xsl:for-each-group,但是id没有完全归入内部。任何人都可以帮忙..

1 个答案:

答案 0 :(得分:0)

假设你需要分组的是Col元素,你可以在这里使用XSLT 2.0样式表:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="xs">

<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>

<xsl:template match="@* | node()">
  <xsl:copy>
    <xsl:apply-templates select="@* , node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="Structure">
  <xsl:copy>
    <xsl:apply-templates select="@*"/>
    <xsl:for-each-group select="Row" group-by="Col/@id">
      <xsl:copy>
        <xsl:apply-templates select="@* , current-group()/node()"/>
      </xsl:copy>
    </xsl:for-each-group>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>