按值分组并使用xslt 1.0合并xml中的子元素

时间:2014-03-13 19:05:21

标签: xslt

我是XSLT的新手,手动更改它需要花费很多时间。请帮助我使用xslt 1.0将xml转换为xml并提供详细信息。我没有找到group by和merge值,属于两个不同的节点。

      <MTR>
           <program>
        <row>
        <rep_number>001</rep_number>
        <program_id>PMP</program_id>
        <name>Program 1</name>
        <acct_no> 2001 </acct_no>
        <value>150</value>
        </row>

        <row>
        <rep_number>002</rep_number>
        <program_id>CSP</program_id>
        <name>Program 2 </name>
        <acct_no> 2002 </acct_no>
        <value>150</value>
        </row>

        <row>
        <rep_number>001</rep_number>
        <program_id>PMP</program_id>
        <name>Program 1</name>
        <acct_no> 2003 </acct_no>
        <value>150</value>
        </row>

        <row>
        <rep_number>001</rep_number>
        <program_id>PMP</program_id>
        <name>Program 1</name>
        <acct_no> 2004 </acct_no>
        <value>150</value>
       </row>           
    </program>
      </MTR>


    **expecting output:**

    <reports>
        <report>
        <rep_number>001</rep_number>
        <program_id>PMP</program_id>
        <name>Program 1</name>
        <acct_no> 2001,2003,2004 </acct_no>
        <value>150</value>
        </report>

       <report>

        <rep_number>002</rep_number>
        <program_id>CSP</program_id>
        <name>Program 2 </name>
        <acct_no> 2002 </acct_no>
        <value>150</value>
       </report>

    </reports>

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 indent="yes" omit-xml-declaration="yes"/>    

    <!-- create a key using a combination of 'rep_number', 'program_id', and 'name' -->

    <xsl:key name="kGroup" match="row" use="concat(rep_number, '+', program_id, '+', name)"/>

    <xsl:template match="/">
        <reports>
            <xsl:apply-templates/>
        </reports>
    </xsl:template>

    <xsl:template match="program">
        <!-- I have used the second method in 
            http://www.jenitennison.com/xslt/grouping/muenchian.xml 
            in testing whether two nodes are identical -->
        <xsl:for-each select="row[count(. | key('kGroup', concat(rep_number, '+', program_id, '+', name))[1]) = 1]">
            <report>
                <!-- copy the nodes -->
                <xsl:copy-of select="rep_number"/>
                <xsl:copy-of select="program_id"/>
                <xsl:copy-of select="name"/>
                <acct_no>
                <!-- loop through key matches -->
                <xsl:for-each select="key('kGroup', concat(rep_number, '+', program_id, '+', name))">
                    <xsl:choose>
                        <!-- checks for position, if 
                            its the last in the group, then
                            do not insert a comma -->
                        <xsl:when test="position()!=last()">
                            <xsl:value-of select="normalize-space(acct_no)"/><xsl:text>,</xsl:text>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:value-of select="normalize-space(acct_no)"/>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:for-each>
                </acct_no>
                <xsl:copy-of select="value"/>
            </report>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

当它应用于您的输入XML时,它会输出:

<reports>

   <report>
      <rep_number>001</rep_number>
      <program_id>PMP</program_id>
      <name>Program 1</name>
      <acct_no>2001,2003,2004</acct_no>
      <value>150</value>
   </report>
   <report>
      <rep_number>002</rep_number>
      <program_id>CSP</program_id>
      <name>Program 2 </name>
      <acct_no>2002</acct_no>
      <value>150</value>
   </report>

</reports>