key grouping on similar items XSLT1.0

63 Views Asked by At

I need to group Itemno for different Level

Example:

Level1:8000000377 - 1
       8000000376 - 1
       8000000378 - 2
       8000000373 - 1
       8000000371 - 1
Level2:8000000373 - 2
<Root>
    <Label>
        
        <Dept>
            <Line>
                
                <Material>
                    <Level>1</Level>
                    <Type>abc</Type>
                    <Itemno>8000000377</Itemno>
                </Material>
                
                <Material>
                    <Level>1</Level>
                    <Type>abc</Type>
                    <Itemno>8000000376</Itemno>
                </Material>
                
                <Material>
                    <Level>1</Level>
                    <Type>123</Type>
                    <Itemno>8000000378</Itemno>
                </Material>
                
                <Material>
                    <Level>2</Level>
                    <Type>rth</Type>
                    <Itemno>8000000373</Itemno>
                </Material>
                
            </Line>
        </Dept>
        
        
        <Dept>
            <Line>
                
                <Material>
                    <Level>1</Level>
                    <Type>34r</Type>
                    <Itemno>8000000372</Itemno>
                </Material>
                
                <Material>
                    <Level>1</Level>
                    <Type>4th</Type>
                    <Itemno>8000000371</Itemno>
                </Material>
                
                <Material>
                    <Level>1</Level>
                    <Type>123</Type>
                    <Itemno>8000000378</Itemno>
                </Material>
                
                <Material>
                    <Level>2</Level>
                    <Type>dvg</Type>
                    <Itemno>8000000373</Itemno>
                </Material>
                
            </Line>
        </Dept>
        
    </Label>
</Root>

I tried key as:

<xsl:key name="s1" match="Material[Level='1']" use="concat(Label ,'|', Itemno)" />
<xsl:key name="s1" match="Material[Level='2']" use="concat(Label ,'|', Itemno)" />

but I am getting key not bound.

Can anyone help me where I am going wrong?

1

There are 1 best solutions below

0
y.arazim On

I adapted the answers from here and here to:

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

<xsl:key name="kLevel" match="Material" use="Level" />
<xsl:key name="kItem" match="Material" use="concat(Level, '|', Itemno)" />

<xsl:template match="/Root">
    <result>
        <xsl:for-each select="//Material[count(. | key('kLevel', Level)[1]) = 1]">
            <level name="{Level}">
                <xsl:variable name="group" select="key('kLevel', Level)" />
                <xsl:for-each select="$group[count(. | key('kItem', concat(Level, '|', Itemno))[1]) = 1]">
                    <item number="{Itemno}" count="{count(key('kItem', concat(Level, '|', Itemno)))}"/>
                </xsl:for-each>
            </level>
        </xsl:for-each>
    </result>
</xsl:template>

</xsl:stylesheet>

This gives me the result:

<?xml version="1.0"?>
<result>
  <level name="1">
    <item number="8000000377" count="1"/>
    <item number="8000000376" count="1"/>
    <item number="8000000378" count="2"/>
    <item number="8000000372" count="1"/>
    <item number="8000000371" count="1"/>
  </level>
  <level name="2">
    <item number="8000000373" count="2"/>
  </level>
</result>

There is a discrepancy between my result and yours: mine has no item 8000000373 at level 1. I think this may be a typo in yours.