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 April 4th, 2007, 01:35 PM
Registered User
 
Join Date: Apr 2007
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)

 
Old April 4th, 2007, 02:33 PM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 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
 
Old April 4th, 2007, 02:37 PM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 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
 
Old April 4th, 2007, 03:47 PM
Registered User
 
Join Date: Apr 2007
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.






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





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