xsl-list
[Top] [All Lists]

Re: [xsl] removing duplicates from a sequence while retaining order

2012-10-08 19:49:46
At 2012-10-08 20:32 -0400, Birnbaum, David J wrote:
Dear XSLT list,

Is there an easy way in XPath (not using XSLT instructions) to select only the first occurrence of a specific value in a sequence of atomic values, so as to return the sequence in the original order, but with re-occurrences of each value after the first appearance of that value removed? For example, given an input sequence:

        ('Matthew','Mark','Luke','Matthew','John')

I want to produce

        ('Matthew','Mark','Luke','John')

I can't rely on using distinct-values() because that isn't guaranteed to keep specifically the *first* occurrence of a value.

In an XSLT context I can construct a temporary tree, poke each value into an element, all on the same level in the hierarchy, and then test for:

*[not(preceding-sibling::* = .)]

but I don't know how to write an XPath predicate that will filter the sequence of *atomic values* the way I want. Is this just a blind spot? Can anyone advise?

If I'm allowed to put the sequence into a variable, then:

T:\ftemp>xslt2 david.xsl david.xsl
<?xml version="1.0" encoding="UTF-8"?>Matthew Mark Luke John
T:\ftemp>type david.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
  version="2.0">

<xsl:template match="/">
<xsl:variable name="items" select="('Matthew','Mark','Luke','Matthew','John')"/>
  <xsl:value-of select="$items[position() = index-of($items,.)[1]]"/>
</xsl:template>

</xsl:stylesheet>

If I'm not allowed to put the sequence into a variable, but I am allowed to duplicate the sequence in the expression:

T:\ftemp>xslt2 david2.xsl david2.xsl
<?xml version="1.0" encoding="UTF-8"?>Matthew Mark Luke John
T:\ftemp>type david2.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
  version="2.0">

<xsl:template match="/">
<xsl:value-of select="('Matthew','Mark','Luke','Matthew','John')[position() = index-of(('Matthew','Mark','Luke','Matthew','John'),.)[1]]"/>
</xsl:template>

</xsl:stylesheet>
T:\ftemp>

I don't think I can do it otherwise, but I only have five minutes this evening to look at this.

I hope this helps.

. . . . . . . . . . Ken

--
Contact us for world-wide XML consulting and instructor-led training
Free 5-hour lecture: http://www.CraneSoftwrights.com/links/udemy.htm
Crane Softwrights Ltd.            http://www.CraneSoftwrights.com/s/
G. Ken Holman                   mailto:gkholman(_at_)CraneSoftwrights(_dot_)com
Google+ profile: https://plus.google.com/116832879756988317389/about
Legal business disclaimers:    http://www.CraneSoftwrights.com/legal


--~------------------------------------------------------------------
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>
--~--

<Prev in Thread] Current Thread [Next in Thread>