Peter
Peter

Reputation: 1796

XSLT 1.0: grouping one value to many values - use of keys?

I have the following simplified XML structure:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<DESADV>
<M_DESADV>
    <G_SG10>
        <G_SG13>
            <S_GIN>
                <id>GIN</id>
                <D_7405_6>BJ</D_7405_6>
                <C_C208_2>
                    <D_7402_8>373500699550026556</D_7402_8>
                </C_C208_2>
            </S_GIN>
        </G_SG13>
    </G_SG10>
    <G_SG10>
        <G_SG17>
            <S_PIA>
                <id>PIA</id>
                <D_4347>1</D_4347>
                <C_C212_2>
                    <D_7140_2>110005</D_7140_2>
                    <D_7143_4>SA</D_7143_4>
                </C_C212_2>
            </S_PIA>
        </G_SG17>
    </G_SG10>
    <G_SG10>
        <G_SG17>
            <S_PIA>
                <id>PIA</id>
                <D_4347>1</D_4347>
                <C_C212_2>
                    <D_7140_2>123456</D_7140_2>
                    <D_7143_4>SA</D_7143_4>
                </C_C212_2>
            </S_PIA>
        </G_SG17>
    </G_SG10>
    <G_SG10>
        <G_SG13>
            <S_GIN>
                <id>GIN</id>
                <D_7405_6>BJ</D_7405_6>
                <C_C208_2>
                    <D_7402_8>3735009999999999</D_7402_8>
                </C_C208_2>
            </S_GIN>
        </G_SG13>
    </G_SG10>
    <G_SG10>
        <G_SG17>
            <S_PIA>
                <id>PIA</id>
                <D_4347>1</D_4347>
                <C_C212_2>
                    <D_7140_2>632154</D_7140_2>
                    <D_7143_4>SA</D_7143_4>
                </C_C212_2>
            </S_PIA>
        </G_SG17>
    </G_SG10>
    <G_SG10>
        <G_SG17>
            <S_PIA>
                <id>PIA</id>
                <D_4347>1</D_4347>
                <C_C212_2>
                    <D_7140_2>887796</D_7140_2>
                    <D_7143_4>SA</D_7143_4>
                </C_C212_2>
            </S_PIA>
        </G_SG17>
    </G_SG10>
</M_DESADV>
</DESADV>

I need to do a mapping so I get the following XML output:

<?xml version="1.0" encoding="UTF-8"?>
<list>
<number>373500699550026556 110005</number>
<number>373500699550026556 123456</number>
<number>3735009999999999 632154</number>
<number>3735009999999999 887796</number>
</list>

I am having trouble getting that output though. I have the following XSLT that I though would work:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">

<xsl:template match="text()"/>

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

<xsl:template match="M_DESADV">
    
    <xsl:for-each select="G_SG10/G_SG17/S_PIA/C_C212_2[D_7143_4='SA']/D_7140_2">
        <number>
            <xsl:value-of select="concat(
                parent::C_C212_2/parent::S_PIA/parent::G_SG17/parent::G_SG10/parent::M_DESADV
                /G_SG10/G_SG13/S_GIN[D_7405_6='BJ']/C_C208_2/D_7402_8,' ',
                .)
                "/>
        </number>
    </xsl:for-each>
</xsl:template>



</xsl:stylesheet>

But my output looks like this which is not what I expect:

<?xml version="1.0" encoding="UTF-8"?>
<list>
<number>373500699550026556 110005</number>
<number>373500699550026556 123456</number>
<number>373500699550026556 632154</number>
<number>373500699550026556 887796</number>
</list>

Can this be solved with Muenchian Grouping? I tried setting up a key but it either selects "D_7402_8" or only "D_7140_2".

Upvotes: 1

Views: 72

Answers (1)

Ian Roberts
Ian Roberts

Reputation: 122414

I don't think you need keys for this, you just need to find, for each G_SG10-that-has-a-G_SG17, its nearest preceding sibling G_SG10-that-has-a-G_SG13:

<xsl:for-each select="G_SG10/G_SG17/S_PIA/C_C212_2[D_7143_4='SA']/D_7140_2">
    <number>
        <xsl:value-of select="concat(
            ancestor::G_SG10/preceding-sibling::G_SG10[G_SG13][1]
            /G_SG13/S_GIN[D_7405_6='BJ']/C_C208_2/D_7402_8,' ',
            .)
            "/>
    </number>
</xsl:for-each>

If the condition in your real XML is more complex than "has a G_SG13" then you just need to encode the relevant condition in the first predicate on the preceding-sibling:: step, e.g.

preceding-sibling::G_SG10[G_SG13/S_GIN/D_7405_6='BJ'][1]

Upvotes: 1

Related Questions