Convert XSL 2.0 count by current-group logic into XSL 1.0 logic

61 Views Asked by At

I'm a novice with XSL and am trying to summarize some XML data based on grouping of substrings of data.

I've been trying to get my head around Muenchian grouping and counting but have not been able to get it to work. I took a look at the XSL 2.0 format and managed to solve my issue in 5 minutes with the code below.

My problem is that I need this to work in XSL 1.0.

Can somebody please help me convert this logic into XSL 1.0 format?

This is the working XSL 2.0 code

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:template match="/">
    <html>
        <head>
            <meta charset="utf-8"/>
            <meta name="viewport" content="initial-scale=1.0, maximum-scale=2.0"/>
        </head>
        <body>
            <p>
                <table align="center">
                    <thead>
                        <tr>
                            <th>Bay</th>
                            <th>Units</th>
                            <th>20'</th>
                            <th>40'</th>
                            <th>45'</th>
                            <th>Breakbulk</th>
                        </tr>
                    </thead>
                    <tbody>
                        <xsl:for-each-group select="StowplanTransactions/Group2"
                            group-by="substring(LocationIdentification/@LocationID, 1, 3)">
                            <xsl:sort select="LocationIdentification/@LocationID"/>
                            <tr>
                                <td>
                                    <xsl:value-of select="current-grouping-key()"/>
                                </td>
                                <td>
                                    <xsl:value-of select="count(current-group())"/>
                                </td>
                                <td>
                                    <xsl:value-of
                                        select="count(current-group()/Group3/EquipmentDetails[substring(@EquipmentSizeTypeIdentification, 1, 1) = '2']/@EquipmentSizeTypeIdentification)"
                                    />
                                </td>
                                <td>
                                    <xsl:value-of
                                        select="count(current-group()/Group3/EquipmentDetails[substring(@EquipmentSizeTypeIdentification, 1, 1) = '4']/@EquipmentSizeTypeIdentification)"
                                    />
                                </td>
                                <td>
                                    <xsl:value-of
                                        select="count(current-group()/Group3/EquipmentDetails[substring(@EquipmentSizeTypeIdentification, 1, 1) = '9' or substring(@EquipmentSizeTypeIdentification, 1, 1) = 'L']/@EquipmentSizeTypeIdentification)"
                                    />
                                </td>
                                <td>
                                    <xsl:value-of
                                        select="count(current-group()/Group3/EquipmentDetails[substring(@EquipmentSizeTypeIdentification, 1, 1) = '']/@EquipmentSizeTypeIdentification)"
                                    />
                                </td>
                            </tr>
                        </xsl:for-each-group>
                    </tbody>
                </table>
            </p>
        </body>
    </html>
</xsl:template>

This is my current XLS 1.0 code. The Grouping is working, and the count of members in the group is working, but I need to count where an attribute has a specific value within the group. Currently the last 4 count fields all show 0.

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:key name="StowageCellBay" match="//StowplanTransactions/Group2/LocationIdentification"
    use="substring(@LocationID, 1, 3)"/>
<xsl:template match="/">
    <html>
        <head>
            <meta charset="utf-8"/>
            <meta name="viewport" content="initial-scale=1.0, maximum-scale=2.0"/>
        </head>
        <body>
            <p>
                <table align="center" border="1">
                    <thead>
                        <tr>
                            <th>Bay</th>
                            <th>Units</th>
                            <th>20'</th>
                            <th>40'</th>
                            <th>45'</th>
                            <th>Breakbulk</th>
                        </tr>
                    </thead>
                    <tbody>
                        <xsl:for-each select="StowplanTransactions/Group2">
                            <xsl:sort select="LocationIdentification/@LocationID"/>
                            <xsl:for-each
                                select="
                                    LocationIdentification[generate-id() =
                                    generate-id(key('StowageCellBay', substring(@LocationID, 1, 3))[1])]">
                                <tr>
                                    <td>
                                        <xsl:value-of select="substring(@LocationID, 1, 3)"/>
                                    </td>
                                    <td>
                                        <xsl:value-of
                                            select="count(key('StowageCellBay', substring(@LocationID, 1, 3)))"
                                        />
                                    </td>
                                    <td>
                                        <xsl:value-of
                                            select="count(Group3/EquipmentDetails[substring(@EquipmentSizeTypeIdentification, 1, 1) = '2']/@EquipmentSizeTypeIdentification)"
                                        />
                                    </td>
                                    <td>
                                        <xsl:value-of
                                            select="count(Group3/EquipmentDetails[substring(@EquipmentSizeTypeIdentification, 1, 1) = '4']/@EquipmentSizeTypeIdentification)"
                                        />
                                    </td>
                                    <td>
                                        <xsl:value-of
                                            select="count(Group3/EquipmentDetails[substring(@EquipmentSizeTypeIdentification, 1, 1) = 'L' or substring(@EquipmentSizeTypeIdentification, 1, 1) = '9']/@EquipmentSizeTypeIdentification)"
                                        />
                                    </td>
                                    <td>
                                        <xsl:value-of
                                            select="count(Group3/EquipmentDetails[substring(@EquipmentSizeTypeIdentification, 1, 1) = '']/@EquipmentSizeTypeIdentification)"
                                        />
                                    </td>
                                </tr>
                            </xsl:for-each>
                        </xsl:for-each>
                    </tbody>
                </table>
            </p>
        </body>
    </html>
</xsl:template>

Here is an example of the XML source

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<StowplanTransactions>
<Group2>
    <LocationIdentification LocationID="0610390" />
    <Group3>
        <EquipmentDetails  EquipmentIdentificationNumber="11111111111"
            EquipmentSizeTypeIdentification="22G1"/>
    </Group3>
</Group2>
<Group2>
    <LocationIdentification LocationID="0340612" />
    <Group3>
        <EquipmentDetails EquipmentIdentificationNumber="22222222222"
            EquipmentSizeTypeIdentification="42G1" />
    </Group3>
</Group2>
<Group2>
    <LocationIdentification LocationID="0650004"/>
    <Group3>
        <EquipmentDetails EquipmentIdentificationNumber="33333333333"
            EquipmentSizeTypeIdentification="" />
    </Group3>
</Group2>
<Group2>
    <LocationIdentification LocationID="0650306"/>
    <Group3>
        <EquipmentDetails EquipmentIdentificationNumber="44444444444"
            EquipmentSizeTypeIdentification="22G1" />
    </Group3>
</Group2>
<Group2>
    <LocationIdentification LocationID="0730220"/>
    <Group3>
        <EquipmentDetails EquipmentIdentificationNumber="55555555555"
            EquipmentSizeTypeIdentification="L591"/>
    </Group3>
</Group2>

1

There are 1 best solutions below

0
On BEST ANSWER

See if this makes sense to you:

XSLT 1.0

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

<xsl:key name="grp" match="Group2" use="substring(LocationIdentification/@LocationID, 1, 3)"/>

<xsl:template match="/StowplanTransactions">
    <table align="center" border="1">
        <thead>
            <tr>
                <th>Bay</th>
                <th>Units</th>
                <th>20'</th>
                <th>40'</th>
                <th>45'</th>
                <th>Breakbulk</th>
            </tr>
        </thead>
        <tbody>
            <xsl:for-each select="Group2[generate-id()=generate-id(key('grp', substring(LocationIdentification/@LocationID, 1, 3))[1])]">
                <xsl:sort select="LocationIdentification/@LocationID"/>
                <xsl:variable name="curr-key" select="substring(LocationIdentification/@LocationID, 1, 3)" />           
                <xsl:variable name="curr-group" select="key('grp', $curr-key)" />
                <tr>
                    <td>
                        <xsl:value-of select="$curr-key"/>
                    </td>
                    <td>
                        <xsl:value-of select="count($curr-group)"/>
                    </td>
                    <td>
                        <xsl:value-of select="count($curr-group/Group3/EquipmentDetails[substring(@EquipmentSizeTypeIdentification, 1, 1) = '2']/@EquipmentSizeTypeIdentification)"/>
                    </td>
                    <td>
                        <xsl:value-of select="count($curr-group/Group3/EquipmentDetails[substring(@EquipmentSizeTypeIdentification, 1, 1) = '4']/@EquipmentSizeTypeIdentification)"/>
                    </td>
                    <td>
                        <xsl:value-of select="count($curr-group/Group3/EquipmentDetails[substring(@EquipmentSizeTypeIdentification, 1, 1) = '9' or substring(@EquipmentSizeTypeIdentification, 1, 1) = 'L']/@EquipmentSizeTypeIdentification)"/>
                    </td>
                    <td>
                        <xsl:value-of select="count($curr-group/Group3/EquipmentDetails[substring(@EquipmentSizeTypeIdentification, 1, 1) = '']/@EquipmentSizeTypeIdentification)"/>
                    </td>
                </tr>
            </xsl:for-each>
        </tbody>
    </table>
</xsl:template>

</xsl:stylesheet>