Wrox Programmer Forums
Go Back   Wrox Programmer Forums > XML > XSLT
|
XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old March 17th, 2009, 10:20 AM
Banned
 
Join Date: Jul 2005
Posts: 317
Thanks: 0
Thanked 0 Times in 0 Posts
Question XSLT/XPath: How to display single node occurence

Hello,

I'm working on a for-each element that will display only one occurrence of a name node, even if there are several occurences of that name in the XML doc. Here's an example of what I need:

XML doc:
<root>
<name>Janice Smith</name>
<name>Janice Smith</name>
<name>Michael Jones</name>
<name>Michael Jones</name>
<name>Michael Jones</name>
</root>

XSLT FOR-EACH ELEMENT:
<xsl:for-each select="root/name"><!-- <<<<---something is missing here -->
<xsl:value-of select="." /><br />
</xsl:for-each>

WANTED RESULT:
Janice Smith
Michael Jones

I'll continue to work on a possible solution until/if I hear get from someone else. Thanks for any help.
 
Old March 17th, 2009, 10:30 AM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

Well in XSLT 2.0 it is easy with the distinct-values function:
Code:
    <xsl:for-each select="distinct-values(root/name)">
      <xsl:value-of select="."/>
      <br/>
    </xsl:for-each>
Or you could use xsl:for-each-group select="root/name" group-by=".".

With XSLT 1.0 you could use Muenchian grouping. Let us know if you need help with that.
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
 
Old March 17th, 2009, 10:33 AM
Banned
 
Join Date: Jul 2005
Posts: 317
Thanks: 0
Thanked 0 Times in 0 Posts
Thumbs up

Thanks Martin,

I'm currently using 1.0, so I can't use that cool distinct-values function. I need to upgrade sometime soon so that I can utilize all of those functions.

Anyway, I was able to come up with a solution that works in 1.0, and here it is:

<xsl:for-each select="root/name[not(text() = ../preceding-sibling::name/text())]">

...and it worked great. Thanks again for your help!
 
Old March 17th, 2009, 10:42 AM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

Using Muenchian grouping should be more efficient for large data:
Code:
  <xsl:key name="k1" match="name" use="."/>
  
  <xsl:template match="/">
    <xsl:for-each select="root/name[generate-id() = generate-id(key('k1', .)[1])]">
      <xsl:value-of select="."/>
      <br/>
    </xsl:for-each>
  </xsl:template>
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog





Similar Threads
Thread Thread Starter Forum Replies Last Post
Validate single node joxa83 XML 3 January 9th, 2009 08:21 AM
convert nodeset to a single node newbies1234 XSLT 2 August 18th, 2008 10:01 AM
XPath to get next node (sibling) jeft0nes XSLT 2 August 8th, 2007 08:30 PM
XPath node selection nkuar XML 1 March 4th, 2006 09:40 PM
select single node bcadmin BOOK: XSLT Programmer's Reference, 2nd Edition 1 November 10th, 2004 12:15 PM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.