[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: removing duplicates in loops

Subject: Re: removing duplicates in loops
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Tue, 2 Apr 2002 09:44:15 +0100
remove duplicates xslt efficient
Hi Yi,

> i have the following xsl and want to remove repeated education and
> honor elements. how should i achieve that?

What you're doing looks roughly OK. You're getting hold of resumeid
elements that are unique within the document with:

  /rowset/row/resumeid[not(preceding::resumeid = .)]

You're sorting these by their value (by resumeid), and creating a
resume element for each. However, you're then using *absolute* paths
to populate the content of the resume. For example:

> <first_name><xsl:value-of select="/rowset/row/fname"/></first_name>

The path /rowset/row/fname goes up to the root node of the source
document, then to the rowset element, then to the row elements and
then picks all the fname elements in the document. When you use
xsl:value-of and select a node set, xsl:value-of gives you the value
of the *first* of the nodes in the node set. So the xsl:value-of
instruction that you're using will always give you the first fname
element in the document.

You actually want the fname element from the row that holds the
resumeid that you're currently on, so you need a *relative* path --
one that doesn't start with a / -- instead:

  <first_name><xsl:value-of select="../fname"/></first_name>

If I were you, I'd actually select *row* elements rather than resumeid
elements, using preceding-sibling:: rather than the preceding:: axis,
as follows, as preceding-sibling:: is more efficient than preceding::
and as it makes the relative paths in the content of the resume
elements that you're creating easier:

  <xsl:for-each
    select="row[not(preceding-sibling::row/resumeid = resumeid)]">
    <xsl:sort select="resumeid" />
    <resume id="{resumeid}">
      <name>
        <first_name><xsl:value-of select="fname"/></first_name>
        <middle_initial><xsl:value-of select="middle"/></middle_initial>
        ...
      </name>
      ...
      <xsl:variable name="resumes"
        select="/rowset/row[resumeid = current()/resumeid]" />
      <xsl:for-each select="$resumes">
        <education>
          ...
        </education>
      </xsl:for-each>
      <xsl:for-each select="$resumes">
        <honor>
          ..
        </honor>
      </xsl:for-each>
    </resume>
  </xsl:for-each>

You might also consider using the Muenchian Method to do the grouping
that you need. See
http://www.jenitennison.com/xslt/grouping/muenchian.html for an
explanation.

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2007 All Rights Reserved.