Re: [xsl] Identifying unique attribute values in nested sibling elements

Subject: Re: [xsl] Identifying unique attribute values in nested sibling elements
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Thu, 29 Sep 2011 07:12:50 -0400
At 2011-09-29 03:31 -0700, Mark wrote:
In processing XML similar to the fragment below, I have identified that within its <Set> element, five <Stamp> elements are of interest (because they all contain <Formats se-tenant="1">).

Then that is your population to be grouped.


how can I gather all of the <Value> elements from the subsequent <Stamp> elements of interest while ignoring:
(1) <Value> elements identical to those already found, and
(2) <Value> elements in <Stamp> elements of no interest?

By grouping them, not by using axes.


For the given XML fragment, I want to find these four <Value> elements and ignore the duplicated <Value> element:
Unique:
kc-value="14"
kc-value="18"
kc-value="18" h-value="50"
kc-value="0" l-value="A"


Duplicate:
kc-value="14"

I hope the solution below helps.


. . . . . . . . . Ken

~/t/ftemp $ cat mark.xml
<?xml version="1.0" encoding="UTF-8"?>
<Set>
<!--possibly other unrelated <Stamp> elements here-->
<Stamp>
     <CatNumbers  pofis-number="1"/>
     <Value kc-value="14"/>
     <Formats se-tenant="1"/>
</Stamp>
<!--possibly other unrelated <Stamp> elements here-->
<Stamp>
     <CatNumbers pofis-number="2"/>
     <Value kc-value="18"/>
     <Formats se-tenant="1"/>
</Stamp>
..... <!--possibly other unrelated stamp elements-->
<Stamp>
     <CatNumbers pofis-number="3"/>
     <Value kc-value="18" h-value="50"/>
     <Formats se-tenant="1"/>
</Stamp>
<!--possibly other unrelated <Stamp> elements here-->
<Stamp>
     <CatNumbers pofis-number="4"/>
     <Value kc-value="14" />
     <Formats se-tenant="1"/>
</Stamp>
<!--possibly other unrelated <Stamp> elements here-->
<Stamp>
     <CatNumbers pofis-number="5"/>
     <Value kc-value="0" l-value="A" />
     <Formats se-tenant="1"/>
</Stamp>
</Set>
~/t/ftemp $ xslt2 mark.xml mark.xsl
Unique:
kc-value=14
kc-value=18
kc-value=18 h-value=50
kc-value=0 l-value=A
Duplicates:
kc-value=14
~/t/ftemp $ cat mark.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
  xmlns:m="urn:X-Mark" exclude-result-prefixes="m"
  version="2.0">
  <xsl:output method="text"/>

  <!--compose a string of attribute names and their values;
      avoid the possibility of co-incidental string values;-->
  <xsl:function name="m:attrs">
    <xsl:param name="this"/>
    <xsl:value-of>
      <xsl:for-each select="$this/@*">
        <xsl:sort select="name(.)"/>
        <xsl:value-of select="name(.),'&#xfdd0;',.,'&#xfdd0;'"/>
      </xsl:for-each>
    </xsl:value-of>
  </xsl:function>

  <!--common reporting-->
  <xsl:function name="m:report">
    <xsl:param name="Stamp"/>
    <xsl:for-each select="$Stamp">
      <xsl:for-each select="Value/@kc-value">
        <xsl:text>kc-value=</xsl:text>
        <xsl:value-of select="."/>
      </xsl:for-each>
      <xsl:for-each select="Value/@* except Value/@kc-value">
        <xsl:text> </xsl:text>
        <xsl:value-of select="name(.)"/>=<xsl:value-of select="."/>
      </xsl:for-each>
      <xsl:text>
</xsl:text>
    </xsl:for-each>
</xsl:function>

  <xsl:template match="Set">
    <!--start with the population desired-->
    <xsl:text>Unique:
</xsl:text>
    <xsl:for-each-group select="Stamp[Formats/@se-tenant=1]"
                        group-by="m:attrs(Value)">
      <xsl:value-of select="m:report(.)"/>
    </xsl:for-each-group>
    <!--duplicates have more than one member-->
    <xsl:text>Duplicates:
</xsl:text>
    <xsl:for-each-group select="Stamp[Formats/@se-tenant=1]"
                        group-by="m:attrs(Value)">
      <!--there are duplicates if a second exists-->
      <xsl:for-each select="current-group()[2]">
        <xsl:value-of select="m:report(.)"/>
      </xsl:for-each>
    </xsl:for-each-group>
  </xsl:template>

</xsl:stylesheet>
~/t/ftemp $


-- Contact us for world-wide XML consulting and instructor-led training Crane Softwrights Ltd. http://www.CraneSoftwrights.com/s/ G. Ken Holman mailto:gkholman@xxxxxxxxxxxxxxxxxxxx Google+ profile: https://plus.google.com/116832879756988317389/about Legal business disclaimers: http://www.CraneSoftwrights.com/legal

Current Thread