XSLT不同的节点结合

时间:2018-10-10 09:23:01

标签: xslt-grouping

我有一个xslt文件,并且我想为不同的国家/地区合并同一客户名称逗号。同一客户可以有多个国家/地区。因此,我想将同一客户的所有国家/地区合并在一起。 下面是我的示例XML:

<ClientReferences>
    <ClientReference>
        <ClientName>ABCDEF PVT. LTD</ClientName>
        <ClientCountry>India</ClientCountry>
    </ClientReference>
    <ClientReference>
        <ClientName>ABCDEF PVT. LTD</ClientName>
        <ClientCountry>China</ClientCountry>
    </ClientReference>
    <ClientReference>
        <ClientName>ABCDEF PVT. LTD</ClientName>
        <ClientCountry>USA</ClientCountry>
    </ClientReference>
    <ClientReference >
        <ClientName>XYZ LIMITED</ClientName>
        <ClientCountry>China</ClientCountry>
    </ClientReference>
</ClientReferences>

我希望结果是:

<ClientReferences>
    <ClientReference>
        <ClientName>ABCDEF PVT. LTD</ClientName>
        <ClientCountry>India,China,USA</ClientCountry>
    </ClientReference>
    <ClientReference>
        <ClientName>XYZ LIMITED</ClientName>
        <ClientCountry>China</ClientCountry>
    </ClientReference>
</ClientReferences>

下面是我的xslt代码:

 <?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/Sections">
        <Sections>
            <ClientReferences>
                <xsl:for-each select="Section/ClientReferences/ClientReference[generate-id() = generate-id(key('sameClient', ClientName)[1])]">
                    <ClientReference>
                        <ClientName>
                            <xsl:value-of select="ClientName"/>
                        </ClientName>
                        <ClientCountry>
                            <xsl:for-each select="ClientName">
                                <xsl:value-of select="ClientCountry"/>
                                <xsl:if test="position() != last()">
                                    <xsl:text>,</xsl:text>
                                </xsl:if>
                            </xsl:for-each>
                        </ClientCountry>
                    </ClientReference>
                </xsl:for-each>
            </ClientReferences>
        </Sections>
    </xsl:template>
</xsl:stylesheet>

1 个答案:

答案 0 :(得分:0)

对每个组使用 XSLT 2.0 功能:

<xsl:template match="ClientReferences">
    <xsl:copy>
        <xsl:for-each-group select="ClientReference" group-by="ClientName">
            <xsl:copy>
                <ClientName><xsl:value-of select="ClientName"/></ClientName>
                <ClientCountry><xsl:value-of select="current-group()/ClientCountry" separator=","/></ClientCountry>
            </xsl:copy>
        </xsl:for-each-group>
    </xsl:copy>
</xsl:template>

请参见https://xsltfiddle.liberty-development.net/bFDb2CX

XSLT 1.0 中采用Muenchian方法

    

<xsl:key name="sameClient" match="ClientReference" use="ClientName"/>
<xsl:template match="ClientReferences">
        <ClientReferences>
            <xsl:for-each select="ClientReference[generate-id(.) = generate-id(key('sameClient', ClientName)[1])]">
                <ClientReference>
                    <ClientName>
                        <xsl:value-of select="key('sameClient', ClientName)[1]/ClientName"/>
                    </ClientName>
                    <ClientCountry>
                        <xsl:for-each select="key('sameClient', ClientName)">
                            <xsl:value-of select="ClientCountry"/>
                            <xsl:if test="position() != last()">
                                <xsl:text>,</xsl:text>
                            </xsl:if>
                        </xsl:for-each>
                    </ClientCountry>
                </ClientReference>
            </xsl:for-each>
        </ClientReferences>
</xsl:template>

请参见https://xsltfiddle.liberty-development.net/bFDb2CX/1