如何组合或合并分组节点?

时间:2010-03-15 20:14:06

标签: xslt grouping

使用XSL:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">
    <xsl:output method="xml"/>
    <xsl:template match="/">
        <records>
            <record>
                <!-- Group record by bigID, for further processing -->
                <xsl:for-each-group select="records/record" group-by="bigID">
                    <xsl:sort select="bigID"/>
                    <xsl:for-each select="current-group()">
                        <!-- Create new combined record -->
                        <bigID>
                            <!-- <xsl:value-of select="."/> -->
                            <xsl:for-each select=".">
                                <xsl:value-of select="bigID"/>
                            </xsl:for-each>
                        </bigID>
                        <text>
                            <xsl:value-of select="text"/>
                        </text>
                    </xsl:for-each>
                </xsl:for-each-group>
            </record>
        </records>
    </xsl:template>
</xsl:stylesheet>

我想改变:

<?xml version="1.0" encoding="UTF-8"?>
<records>
    <record>
        <bigID>123</bigID>
        <text>Contains text for 123</text>
        <bigID>456</bigID>
        <text>Some 456 text</text>
        <bigID>123</bigID>
        <text>More 123 text</text>
        <bigID>123</bigID>
        <text>Yet more 123 text</text>
    </record>
</records>

成:

<?xml version="1.0" encoding="UTF-8"?>
<records>
    <record>
        <bigID>123
            <text>Contains text for 123</text>
            <text>More 123 text</text>
            <text>Yet more 123 text</text>
        </bigID>
        <bigID>456
            <text>Some 456 text</text>
        </bigID>
    </record>
</records>

现在,我只是单独列出分组<bigID&gt; s。我错过了分组后的步骤,我将分组<bigID&gt;组合在一起。节点。我怀疑是我需要以某种方式使用“密钥”功能,但我不确定。

感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

以下是想要的XSLT 2.0转换

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

    <xsl:key name="kTextforId" match="text"
         use="preceding-sibling::bigID[1]"/>

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

  <xsl:template match="record">
   <record>
    <xsl:for-each-group select="bigID" group-by=".">
     <bigID>
       <xsl:sequence select="current-grouping-key()"/>

       <xsl:copy-of select=
       "key('kTextforId', current-grouping-key())"/>
     </bigID>
    </xsl:for-each-group>
   </record>
  </xsl:template>
</xsl:stylesheet>

在提供的XML文档上执行时,会生成所需的结果。

答案 1 :(得分:-1)

在XSLT 2.0中,您不需要用于分组的键。

由于您只是复制组中的text元素,因此可以删除内部for-each。

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" indent="yes" />

    <xsl:template match="/">
        <records>
            <record>
                <xsl:for-each-group select="records/record/bigID" group-by=".">
                    <xsl:sort select="." data-type="number" />
                    <bigID>
                        <xsl:value-of select="." />
                        <xsl:copy-of select="current-group()/following-sibling::text[1]" />
                    </bigID>
                </xsl:for-each-group>
            </record>
        </records>
    </xsl:template>

</xsl:stylesheet>

如果您想要输出bigID元素后跟其文本元素,那么我的循环将替换为以下内容。

<xsl:for-each-group select="records/record/bigID" group-by=".">
    <xsl:sort select="." data-type="number" />
    <xsl:copy-of select="." />
    <xsl:copy-of select="current-group()/following-sibling::text[1]" />
</xsl:for-each-group>