Wrox Programmer Forums

Need to download code?

View our list of code downloads.

Go Back   Wrox Programmer Forums > XML > XSLT
Password Reminder
Register
Register | FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read
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 tens of thousands of software programmers and website developers including Wrox book authors and readers. As a guest, you can read any forum posting. By joining today you can post your own programming questions, respond to other developers’ questions, and eliminate the ads that are displayed to guests. Registration is fast, simple and absolutely free .
DRM-free e-books 300x50
Reply
 
Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old April 4th, 2007, 01:35 PM
Registered User
 
Join Date: Apr 2007
Location: , , .
Posts: 5
Thanks: 0
Thanked 0 Times in 0 Posts
Default Removing duplicate nodes post-process

(newbie question)
I'm trying to do some post-processing on the results of an XSLT that was made by someone else. My goal is to trim off some duplicate nodes from the results of their transformation. I want my final transform to be a one-step process, so I capture the results of the previous transform in a variable and then I want to modify the nodes in that variable (node-set?).

<xsl:variable name="ORIGINAL_RESULTS">

</xsl:variable>

So, after the above is run, the value of $ORIGINAL_RESULTS is the following:
<XML>
  <A>
    <B>
      <uniqueName>UN1</uniqueName>
    </B>
    <B>
      <uniqueName>UN2</uniqueName>
    </B>
    <B>
      <uniqueName>UN1</uniqueName>
    </B>
  </A>
</XML>

The modification I want to perform is to trim out all the nodes that have duplicate values for their uniqueName children. (i.e. The third <B> node above will be trimmed out) I think the test I want to run is the following:

<xsl:if test="uniqueName">
  <xsl:choose>
    <xsl:when test="uniqueName/text() != preceding-sibling::uniqueName/text()">
      <-- good, output -->
    </xsl:when>
    <xsl:otherwise>
      <-- bad, don't output>
    </xsl:otherwise>
  </xsl:choose>
</xsl:if>

If the node tested has a child named "uniqueName" and the value of that child already exists previously, don't output it.

My problem is that I don't know how to take the variable ORIGINAL_RESULTS and apply the "filter" I've made and have it output the entire XML results except what I've filtered out. Any ideas? (This is probably very simple, I'm new to XSLT though)w how to take the variable ORIGINAL_RESULTS and apply the "filter" I've made and have it output the entire XML results except what I've filtered out. Any ideas? (This is probably very simple, I'm new to XSLT though)

Reply With Quote
  #2 (permalink)  
Old April 4th, 2007, 02:33 PM
mhkay's Avatar
Wrox Author
Points: 18,438, Level: 59
Points: 18,438, Level: 59 Points: 18,438, Level: 59 Points: 18,438, Level: 59
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Apr 2004
Location: Reading, Berks, United Kingdom.
Posts: 4,954
Thanks: 0
Thanked 290 Times in 285 Posts
Default

>I want my final transform to be a one-step process, so I capture the results of the previous transform in a variable

Actually it's a two-stage process whether the code is all in one stylesheet or in two. Writing a transformation pipeline within a single stylesheet is perhaps operationally more convenient than writing it as multiple stylesheets, but the coding is more awkward because of the need to use multiple modes, it can be harder to debug, it's no faster, and you get fewer opportunities to create reusable or reconfigurable code. Also it can't be done using strict XSLT 1.0 without the node-set() extension.

But if you want to do it, the pattern is

<xsl:variable name="temp">
  <xsl:apply-templates mode="phase1"/>
</xsl:variable>

<xsl:apply-templates select="$temp" mode="phase2"/>

or in XSLT 1.0

<xsl:apply-templates select="xx:node-set($temp)" mode="phase2"/>

where xx:node-set() is an extension function provided in nearly all XSLT 1.0 processors (but in different vendor namespaces).



Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
Reply With Quote
  #3 (permalink)  
Old April 4th, 2007, 02:37 PM
mhkay's Avatar
Wrox Author
Points: 18,438, Level: 59
Points: 18,438, Level: 59 Points: 18,438, Level: 59 Points: 18,438, Level: 59
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Apr 2004
Location: Reading, Berks, United Kingdom.
Posts: 4,954
Thanks: 0
Thanked 290 Times in 285 Posts
Default

<xsl:template match="*"> -- * means for all the elements
  <xsl:element name="{local-name()}" namespace="preferred-uri"> -- means element name is always local-name
    <xsl:copy-of select="@*"/> -- means what ?
    <xsl:apply-templates/> -- means what ?
  </xsl:element>
</xsl:template>

If you don't understand this code then you probably ought to take a couple of days off coding and read a good XSLT book (I can recommend one...).

It's a variant on a very commonly used template rule (known as the "identity template") which copies elements unchanged from the input to the output - typically it's supplemented by other template rules that make small changes to specific elements. In this case the xsl:element instruction creates a new element with the same local name as the original but a different namespace URI. The copy-of instruction copies all the attributes unchanged, and the apply-templates call says "process the children" (if you don't know this one then you REALLY should be reading rather than coding!)

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
Reply With Quote
  #4 (permalink)  
Old April 4th, 2007, 03:47 PM
Registered User
 
Join Date: Apr 2007
Location: , , .
Posts: 5
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Success!

Thanks for your help. I've read some tutorials and have an XSLT book, so I understand most of the terminology. I'm in the unfortunate position of being thrown in the middle of a complex XSLT project with no implementation experience.

Your example template was exactly what I needed. I had seen the identity template in the XSLT spec and knew I needed to use it *somehow* but I just didn't know how.

Thanks again.

Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Removing duplicate entries avantikad XSLT 2 January 2nd, 2008 12:29 PM
Removing duplicate Value Row milindsaraswala Excel VBA 0 November 14th, 2007 06:11 PM
Removing the Duplicate anukagni Access 3 August 31st, 2006 12:57 AM
Removing nodes with an XSLT Jza XSLT 2 April 19th, 2006 10:06 AM
Removing Duplicate Fields antonides Access 2 December 1st, 2003 07:37 PM



All times are GMT -4. The time now is 04:33 AM.


Powered by vBulletin®
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.
© 2013 John Wiley & Sons, Inc.