List unique values of an attribute within a group only for specific criteria in XSL 1.0

70 views Asked by At

I need to list the unique values of an attribute in a group, when another attribute has a specific value. Making this work in XSL 1.0 is very tricky to understand.

Thanks to another post, I now have the groupings defined to allow me to perform counts when attributes match specific criteria. However I'm stumped on being able to list only unique values for one specific attribute, where another attribute is equal to a specific value, but only within the members of the current group.

As always, this will make more sense with example source data and code.

Here is sample XML

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Group1>
  <Group2>
    <LocationIdentification LocationID="0610390" />
    <LocationIdentification1 LocationQualifier="12" LocationID="USLGB"/>
  </Group2>
  <Group2>
    <LocationIdentification LocationID="0610612" />
    <LocationIdentification1 LocationQualifier="12" LocationID="USLAX"/>
  </Group2>
  <Group2>
    <LocationIdentification LocationID="0650004"/>
    <LocationIdentification1 LocationQualifier="12" LocationID="USLGB"/>
  </Group2>
  <Group2>
    <LocationIdentification LocationID="0650306"/>
    <LocationIdentification1 LocationQualifier="6" LocationID="USLAX"/>
   </Group2>
   <Group2>
    <LocationIdentification LocationID="0650220"/>
    <LocationIdentification1 LocationQualifier="12" LocationID="USLGB"/>
   </Group2>
</Group1>

I have XSL set to create groups based on the first 3 characters of the attribute LocationID from the LocationIdentification node.

XSL 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="/Group1">
<table align="center" border="1">
    <thead>
        <tr>
            <th>Bay</th>
            <th>Units</th>
            <th>Locations</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>
                <!-- NEW CODE NEEDS TO GO HERE -->
                </td>
            </tr>
        </xsl:for-each>
    </tbody>
</table>
</xsl:template>

</xsl:stylesheet>

What I need to figure out, is how to list unique values of LocationID within LocationIdentification1 where LocationQualifier='12'

Desired Output

<table align="center" border="1">
  <thead>
    <tr>
        <th>Bay</th>
        <th>Count</th>
        <th>Location(s)</th>
    </tr>
  </thead>
  <tbody>
   <tr>
    <td>061</td>
    <td>2</td>
    <td>USLGB USLAX</td>
  </tr>
  <tr>
    <td>065</td>
    <td>3</td>
    <td>USLGB</td>
  </tr>
</table>

Notice that Bay 65 has a count of 3, but only 2 of the members have a LocationQualifier of 12, and they both have the same value for LocationID, hence the output should only list USLGB for Location(s).

1

There are 1 answers

0
michael.hor257k On BEST ANSWER

You need to do another round of Muenchian grouping:

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:key name="loc12" match="LocationIdentification1[@LocationQualifier='12']" use="concat(substring(../LocationIdentification/@LocationID, 1, 3), '|', @LocationID)"/>

<xsl:template match="/Group1">
    <table align="center" border="1">
        <thead>
            <tr>
                <th>Bay</th>
                <th>Units</th>
                <th>Locations</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:for-each select="$curr-group/LocationIdentification1[@LocationQualifier='12'][generate-id()=generate-id(key('loc12', concat($curr-key, '|', @LocationID))[1])]">
                            <xsl:value-of select="@LocationID"/>
                            <xsl:text> </xsl:text>
                        </xsl:for-each>
                    </td>
                </tr>
            </xsl:for-each>
        </tbody>
    </table>
</xsl:template>

</xsl:stylesheet>