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

February 16th, 2009, 08:50 AM
|
|
Authorized User
|
|
Join Date: Jan 2009
Posts: 36
Thanks: 3
Thanked 0 Times in 0 Posts
|
|
removing duplicate nodes
Hi,
I'm trying to the the following
<!-- creating a variable -->
<xsl:variable name="locationCodes">
<xsl:for-each select="Output/../../../insureditems"> <xsl:variable name="code">
<xsl:call-template name="scrollLocationLink">
<xsl:with-param name="polbr" select="../POLBRR"/> </xsl:call-template>
</xsl:variable>
<xsl:variable name="occupancy">
<xsl:value-of select="OPCT"/>
</xsl:variable>
<xsl:value-of select="concat($code,'/' ,$occupancy)"/>
<xsl:if test="not(position( ) = last( ) )">
<xsl:text>#</xsl:text>
</xsl:if> </xsl:for-each>
</xsl:variable>
<!-- getting a nodeset using the tokenize function -->
<xsl:variable name="listLocationCodes" select="tokenize($locationCodes,'#') "/>
I'm trying to elimate duplicate nodes by doing the following
<xsl:variable name="listLocationCodesNoDups" select="$listLocationCodes[not( .= preceding-sibling:: *)] "/>
this is not working i'm using the xmlspy built in parser.
Anyone could assis me in solving this
Thanks
|
|

February 16th, 2009, 09:17 AM
|
|
Friend of Wrox
|
|
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
|
|
tokenize suggests you use XSLT 2.0.
If you want to remove duplicates from a sequence of strings like that returned by the tokenize function then simply use the function distinct-values http://www.w3.org/TR/xpath-functions...istinct-values
Code:
<xsl:variable name="listLocationCodesNoDups" select="distinct-values($listLocationCodes)"/>
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
|
|

February 16th, 2009, 09:28 AM
|
 |
Wrox Author
|
|
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
|
|
Further to Martin's response, the reason your code doesn't work is that tokenize() returns a sequence of strings (not nodes), and strings don't have preceding siblings. Only nodes have siblings.
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
|
|

February 16th, 2009, 10:19 AM
|
|
Authorized User
|
|
Join Date: Jan 2009
Posts: 36
Thanks: 3
Thanked 0 Times in 0 Posts
|
|
martin & micheal ,
thanks for your reply.
I would like to know how i can elimate duplicate nodes if i create a node set as follows
<xsl:variable name="locationCodes">
<xsl:for-each select="Output/../../../insureditems"> <r>
<c1>
<xsl:call-template name="scrollLocationLink">
<xsl:with-param name="polbr" select="../POLBRR"/>
</xsl:call-template>
</c1>
<c2><xsl:value-of select="OPCT"/></c2>
</r>
</xsl:for-each>
</xsl:variable>
<xsl:for-each select="exslt:node-set($locationCodes)/*">
<xsl:if test="$locationCodes[not(.=preceding-sibling:: *)]">
<locCode><xsl:value-of select="c1"/></locCode>
<occupancy><xsl:value-of select="c2"/></occupancy>
</xsl:if>
</xsl:for-each>
i would like to know what is it that i'm not doing correctly
thanks
|
|

February 16th, 2009, 10:32 AM
|
 |
Wrox Author
|
|
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
|
|
I'm having to make guesses because you haven't shown your called template. However,
(a) exslt:node-set($locationCodes)/* selects a sequence that contains <r> elements, whose children are <c1> and <c2> elements, and in that situation, comparing the string value of each <r> element with its preceding siblings, (the string value being the concatenation of the <c1> and <c2> values), would seem a bit surprising.
(b) There's something wrong here:
<xsl:for-each select="exslt:node-set($locationCodes)/*">
<xsl:if test="$locationCodes[not(.=preceding-sibling:: *)]">
because the value of the test doesn't depend on which node you are currenly processing. I think you meant either
<xsl:for-each select="exslt:node-set($locationCodes)/*[not(.=preceding-sibling:: *)]">
or
<xsl:for-each select="exslt:node-set($locationCodes)/*">
<xsl:if test="not(.=preceding-sibling:: *)">
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
|
|

February 16th, 2009, 10:32 AM
|
|
Friend of Wrox
|
|
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
|
|
Try whether
Code:
<xsl:for-each select="exslt:node-set($locationCodes)/*[not(c1 = preceding-sibling::*/cs)]">
<locCode><xsl:value-of select="c1"/></locCode>
<occupancy><xsl:value-of select="c2"/></occupancy>
</xsl:for-each>
works.
But I am confused as to why you make use of exslt:node-set, your original post seemed to be XSLT 2.0 which does not need that function at all and which would allow you to use xsl:for-each-group e.g.
Code:
<xsl:for-each-group select="$locationCodes/*" group-by="c1">
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
|
|

February 16th, 2009, 10:40 AM
|
|
Authorized User
|
|
Join Date: Jan 2009
Posts: 36
Thanks: 3
Thanked 0 Times in 0 Posts
|
|
Thank you for both of your help.
I wanted to get a solution that works for xsl 1.0 that's why i tried the node-set method.
Thanks
|
|
 |