key on unknown named Element

I have a XML-Structure like this:

<Rootname>  
<FIRST a="1" otherhattrs="whatever">  
</FIRST>
<GROUPB a="b2" b="12" c="b456">
    <SET NR="01">
        <ENTRY type="10" otherhattr="whatever"/>
    </SET>
    <SET NR="02">
        <ENTRY type="10" otherhattr="whatever"/>
        <ENTRY type="10" otherhattr="whatever"/>
        <ENTRY type="20" otherhattr="whatever"/>
    </SET>
</GROUPB>
<GROUPC a="c3" b="23">
    <SET NR="01">
        <ENTRY type="10" otherhattr="whatever"/>
    </SET>
    <SET NR="02">
        <ENTRY type="10" otherhattr="whatever"/>
        <ENTRY type="30" otherhattr="whatever"/>
        <ENTRY type="50" otherhattr="whatever"/>
    </SET>
</GROUPC>
<GROUPD a="d4" b="34">
    <SET NR="02">
        <ENTRY type="10" otherhattr="whatever"/>
    </SET>
    <SET NR="03">
        <ENTRY type="50" otherhattr="whatever"/>
        <ENTRY type="50" otherhattr="whatever"/>
        <ENTRY type="60" otherhattr="whatever"/>
    </SET>
</GROUPD>
</Rootname>

My Result has to be this:

1|b2|b456|01|10|1
1|b2|b456|02|10|2
1|b2|b456|02|20|1
1|c3|23|01|10|1
1|c3|23|02|10|1
1|c3|23|02|30|1
1|c3|23|02|50|1
1|d4|34|02|10|1
1|d4|34|03|50|2
1|d4|34|03|60|1

The logic is a little bit complex, but i will describe:
There are different Groups(GROUP) all belonging to the element FIRST. So first of all I need the attributes “a” of them(FIRST and GROUP). Second step is I need the number(NR) of the SET. Third and last step is I need the “type” of the ENTRY and the quantity of Entries (ENTRY) with the same type in the same SET.

Now there is an Exception:
GROUPB is a special one, if there is an attribute “c”, I don’t need “b” but “c”.

I thought I could solve my main-problem (the number of entries with same type in same set) by a key with {GROUP-attribute “a”, SET-attribute “NR” and ENTRY-attribute “type”} but I’m frustrated, getting no keys or anything back.

My last working XSL was this, with the problem that it sorts out ENTRIES in other GROUPS and SETS:

<xsl:output method="text" encoding="ISO-8859-15" indent="no"/>

<xsl:template match="/">

    <xsl:variable name="a" select="/*/FIRST/@a"/>

    <xsl:if test="string($a) != ''">
        <xsl:for-each select="/*/GROUPC[string(@a) != ''] | /*/GROUPB[string(@a) != '']| /*/GROUPD[string(@a) != '']">
            <xsl:sort select="@a"/>
            <xsl:variable name="out">
                <xsl:apply-templates select=".">
                    <xsl:with-param name="a" select="$a"/>
                </xsl:apply-templates>
            </xsl:variable>
            <xsl:value-of select="$out"/>
        </xsl:for-each>
    </xsl:if>
</xsl:template>    

<xsl:template match="GROUPB">
    <xsl:param name="a"/>

    <xsl:variable name="begin">
        <xsl:choose>
            <xsl:when test="@c">
                <xsl:value-of select="concat($a, '|', @a,'|',@c,'|')"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="concat($a, '|', @a,'|',@b,'|')"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>
    <xsl:variable name="result">
        <xsl:apply-templates select="SET/ENTRY">
            <xsl:with-param name="begin" select="$begin"/>
        </xsl:apply-templates>
    </xsl:variable>
    <xsl:value-of select="$result" />
</xsl:template>    

<xsl:template match="GROUPC">
    <xsl:param name="a"/>

    <xsl:variable name="begin">
        <xsl:value-of select="concat($a, '|', @a,'|',@b,'|')"/>
    </xsl:variable>
    <xsl:variable name="result">
        <xsl:apply-templates select="SET/ENTRY">
            <xsl:with-param name="begin" select="$begin"/>
        </xsl:apply-templates>
    </xsl:variable>
    <xsl:value-of select="$result" />
</xsl:template>

<xsl:template match="GROUPD">
    <xsl:param name="a"/>

    <xsl:variable name="begin">
        <xsl:value-of select="concat($a, '|', @a,'|',@b,'|')"/>
    </xsl:variable>
    <xsl:variable name="result">
        <xsl:apply-templates select="SET/ENTRY">
            <xsl:with-param name="begin" select="$begin"/>
        </xsl:apply-templates>
    </xsl:variable>
    <xsl:value-of select="$result" />
</xsl:template>

<xsl:key name="art" match="ENTRY" use="@type"/>

<xsl:template match="SET">
    <xsl:param name="begin"/>
    <xsl:variable name="nummer">
        <xsl:value-of select="@NR"/>
    </xsl:variable>
    <xsl:for-each select="ENTRY[generate-id() = generate-id(key('art',@type))]">
            <xsl:value-of select="concat($begin, $nummer, '|', @type, '|', count(../ENTRY[@type=current()/@type]))" /><xsl:text>
</xsl:text>
    </xsl:for-each>
</xsl:template>

A last sentence, there could be GROUPS and SETS and ENTRIES without one of the wanted attributes, these ones shouldn’t appear in the result.

Anybody can help me?

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s