xsl-list
[Top] [All Lists]

Re: [xsl] XPath question concerning distinct-values()

2012-08-08 09:02:50
Hi Thorsten,
    I agree, that the approach suggested by Mike is the most elegant
from all the approaches suggested in this thread.

The subject line of your post mentioned, "XPath question concerning
distinct-values()", which probably made many of us think that use of
distinct-values() function was needed in the solution you were
seeking. But that is fine, since de-duplicating of data (which
distinct-values() does) was needed to solve this use case. As evident
in Mike's solution, the for-each-group internally does de-duplicating
on a "key field" and builds the groups keyed by the "key field".

You've cited <xsl:key> from my solution. The XSLT "key" construct,
builds a kind of in-memory index (identified by the "match" and "use"
attributes of <xsl:key>). Later in an XSLT stylesheet, when we use the
"key()" function to lookup (for a specific value of the "key") the
index built by <xsl:key>, they key() function returns the matching
nodes from an XML instance document. This is an efficient way to look
up data (the difference may be significant, for large amounts of data)
from XML instance documents. The other approach I suggested, did a
manual lookup of data by an XPath expression.


On Wed, Aug 8, 2012 at 2:06 PM, Thorsten <xsl-list(_at_)vw-freaks(_dot_)net> 
wrote:
Hello Michael,
hello Mukul,

I've used Michael's suggestion, cause it seems to be the simplest way to do
this, as he wrote too.

Michael Kay <mike(_at_)saxonica(_dot_)com> hat am 3. August 2012 um 15:20 
geschrieben:>
It's simplest to use xsl:for-each-group for this.

<xsl:template match="pricelist">
<xsl:for-each-group select="item" group-by="order-number">
<xsl:value-of select="current-group()[1]/(order-number, price),
'&#xa;'"/>
</xsl:for-each-group>
</xsl:template>


Michael Kay
Saxonica


Mukul, your solutions are really interessting! Thank you too. Maybe I can use
something like that somewhen!
(Well, never ever used <xsl:key> before...)


Mukul Gandhi <gandhi(_dot_)mukul(_at_)gmail(_dot_)com> hat am 3. August 2012 
um 18:01
geschrieben:> Hi Thorsten,
Here are few more 2.0 approaches (hopefully, would meet your
requirement) to solve this problem:

1)

<xsl:template match="/">
<xsl:variable name="unique-order-nums"
select="distinct-values(pricelist/item/order-number)"/>
<xsl:variable name="docRoot" select="/"/>
<xsl:for-each select="$unique-order-nums">
<xsl:value-of select="current()"/><xsl:text>
</xsl:text><xsl:value-of select="$docRoot/pricelist/item[order-number
= current()][1]/price"/><xsl:text>&#xA;</xsl:text>
</xsl:for-each>
</xsl:template>


2)

<xsl:key name="item-key" match="item" use="order-number"/>

<xsl:template match="/">
<xsl:variable name="unique-order-nums"
select="distinct-values(pricelist/item/order-number)"/>
<xsl:variable name="docRoot" select="/"/>
<xsl:for-each select="$unique-order-nums">
<xsl:value-of select="current()"/><xsl:text>
</xsl:text><xsl:value-of select="key('item-key', current(),
$docRoot)[1]/price"/><xsl:text>&#xA;</xsl:text>
</xsl:for-each>
</xsl:template>





-- 
Regards,
Mukul Gandhi

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--