[Home] [By Thread] [By Date] [Recent Entries]
Hi Ken and Martin,
Thank you both. I have combined my answers to you. My eventual solution will have to be generalized to address five similar problems. Ken: Your solution will take a bit of time for me to implement and revise for my desired XHTML output. It is nearly 5 am here and I have been working all night, so may have to take a nap first. Martin: For complex and unrelated reasons, as I said in my earlier email, the processing must take place within the context of that *unique* <Stamp> element with identical values for the pofis-number and se-tenant attributes. I tried to accomplish this by rewriting your first "for-each-group select" as: <xsl:template match="Stamp"> <!-- once the signal is raised that I am in the correct <Stamp> context, do this --> <xsl:for-each-group select="../Stamp" group-by="Formats/@se-tenant"> I thought the "../Stamp" would get me your first group for the current<Set> but got no output. Any Idea why? Of course, I need to get some sleep and things may be clearer after I nap. Also, in your statement: <xsl:for-each-group select="current-group()" select="string-join(Value/@*, '|'">, I assumed the second "select" was a typo for "group-by". Is that assumption correct? I am very weak with XPath, so will have to look up what your expressions mean so that I can format my desired XHTML output. Thanks all, Mark -----Original Message----- From: G. Ken Holman Sent: Thursday, September 29, 2011 4:12 AM To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx Subject: Re: Identifying unique attribute values in nested sibling elements 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: 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: 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(.),'',.,''"/>
</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 $
|

Cart



