对分组数据进行分组并在XSLT中迭代每个分组数据

时间:2015-08-11 10:30:02

标签: xslt

团队,

需要您的帮助才能在XSLT中对数据进行分组。

要求:

  1. 基于report_number
  2. 的分组数据
  3. 组步骤1基于program_name输出数据
  4. 遍历每个分组数据并按预期输出创建XML
  5. 我能够执行前两个步骤。我无法达成逻辑 第3步。

    输入:

    <?xml version="1.0" ?>
    <MTR>
        <program>
            <program_row>
                <report_number>1</report_number>
                <program_id>PMP</program_id>
                <program_name>Portfolio Manager Program</program_name>
                <ssn_tin>1111111111</ssn_tin>
                <acct_number>1111111111</acct_number>
                <total_value/>
            </program_row>
            <program_row>
                <report_number>1</report_number>
                <program_id>PMP</program_id>
                <program_name>Portfolio Manager Program</program_name>
                <ssn_tin>2222222222</ssn_tin>
                <acct_number>2222222222</acct_number>
                <total_value/>
            </program_row>
            <program_row>
                <report_number>1</report_number>
                <program_id>PMP</program_id>
                <program_name>Customer Manager Program</program_name>
                <ssn_tin>3333333333</ssn_tin>
                <acct_number>3333333333</acct_number>
                <total_value/>
            </program_row>
            <program_row>
                <report_number>1</report_number>
                <program_id>PMP</program_id>
                <program_name>Portfolio Manager Program</program_name>
                <ssn_tin>4444444444</ssn_tin>
                <acct_number>4444444444</acct_number>
                <total_value/>
            </program_row>
            <program_row>
                <report_number>1</report_number>
                <program_id>PMP</program_id>
                <program_name>Relationship Manager Program</program_name>
                <ssn_tin>55555555555</ssn_tin>
                <acct_number>55555555555</acct_number>
                <total_value/>
            </program_row>
            <program_row>
                <report_number>2</report_number>
                <program_id>PMP</program_id>
                <program_name>Ringo Manager Program</program_name>
                <ssn_tin>6666666666</ssn_tin>
                <acct_number>6666666666</acct_number>
                <total_value/>
            </program_row>
        </program>
    </MTR>
    

    预期产出:

    <?xml version="1.0" encoding="UTF-8"?>
    <MTR>
    <reports>
        <report>
            <report_number>1</report_number>
            <headers>
                <header>
                    <prog_name>Portfolio Manager Program</prog_name>
                    <acct_no>1111111111,2222222222,55555555555</acct_no>
                </header>
                <header>
                    <prog_name>Customer Manager Program</prog_name>
                    <acct_no>3333333333</acct_no>
                </header>
                <header>
                    <prog_name>Relationship Manager Program</prog_name>
                    <acct_no>4444444444</acct_no>
                </header>
            </headers>
        </report>
        <report>
            <report_number>2</report_number>
            <headers>
                <header>
                    <prog_name>Ringo Manager Program</prog_name>
                    <acct_no>6666666666</acct_no>
                </header>           
            </headers>
        </report>
    </reports>
    </MTR>
    

    不完整的XSLT:

    <xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">   
        <xsl:output method="xml" indent="yes" />
    
        <xsl:key name="kGroup" match="program_row" use="report_number"/>
        <xsl:key name="progNameGroup" match="program_row" use="program_name"/>
    
        <xsl:template match="MTR">
            <MTR>
    
                <xsl:copy-of select="emb_disc" />
    
                <xsl:copy-of select="emb_foot_note" />
    
                <reports>
                <xsl:for-each select="program/program_row[generate-id(.) = generate-id(key('kGroup', report_number)[1])]">
                    <report>
    
                        <headers>
                            <xsl:for-each select="key('kGroup', report_number)[generate-id() = generate-id(key('progNameGroup', program_name)[1])]">
                                <xsl:for-each select="key('progNameGroup', program_name)">
                                    <header>
                                        <prog_name></prog_name>
                                        <acct_no></acct_no>
                                    </header>                                       
                                </xsl:for-each>
                            </xsl:for-each>     
                        </headers>
                    </report>       
                </xsl:for-each>
                </reports>
    
            </MTR>
        </xsl:template> 
    
    </xsl:stylesheet>       
    

1 个答案:

答案 0 :(得分:0)

以下是更正,您需要确保第二级密钥包含第一级密钥的值,然后您需要输出项目:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">   
    <xsl:output method="xml" indent="yes" />

    <xsl:key name="kGroup" match="program_row" use="report_number"/>
    <xsl:key name="progNameGroup" match="program_row" use="concat(report_number, '|', program_name)"/>

    <xsl:template match="MTR">
        <MTR>

            <xsl:copy-of select="emb_disc" />

            <xsl:copy-of select="emb_foot_note" />

            <reports>
            <xsl:for-each select="program/program_row[generate-id(.) = generate-id(key('kGroup', report_number)[1])]">
                <report>
                    <xsl:copy-of select="report_number"/>
                    <headers>
                        <xsl:for-each select="key('kGroup', report_number)[generate-id() = generate-id(key('progNameGroup', concat(report_number, '|', program_name))[1])]">
                            <header>
                                <prog_name><xsl:value-of select="program_name"/></prog_name>
                                <acct_no>
                                    <xsl:for-each select="key('progNameGroup', concat(report_number, '|', program_name))/acct_number">
                                        <xsl:if test="position() > 1">,</xsl:if>
                                        <xsl:value-of select="."/>
                                    </xsl:for-each>
                                </acct_no>
                            </header>                                                                  
                        </xsl:for-each>     
                    </headers>
                </report>       
            </xsl:for-each>
            </reports>

        </MTR>
    </xsl:template> 

</xsl:stylesheet> 

http://xsltransform.net/6qVRKx9的在线示例。