p2p.wrox.com Forums

Need to download code?

View our list of code downloads.


Go Back   p2p.wrox.com Forums > XML > XSLT
I forgot my password Register Now
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 p2p Programmer to Programmer discussion community. This is a community of more than 40,000 computer programmers including Wrox book authors and readers. As a guest, you can read any forum posting. By joining our free Wrox p2p community you can post your own programming questions and respond to other programmers’ questions. Registered users also don't have to see the ads that are displayed to guests. Registration is fast, simple and absolutely free so please, join today!
Join today and post to win prizes! Post more to increase your chances of being Wrox’s top poster of the month.

Reply
 
Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old July 6th, 2009, 05:04 PM
Registered User
Points: 35, Level: 1
Points: 35, Level: 1 Points: 35, Level: 1 Points: 35, Level: 1
Activity: 8%
Activity: 8% Activity: 8% Activity: 8%
 
Join Date: Jul 2009
Posts: 9
Thanks: 0
Thanked 0 Times in 0 Posts
Default sorting nodes

Hi all,

Please help me in figuring out how to code for this xml transformation
Thwe final outcome of the xml should contain all employee with highest salary from different TypeCde (Taking into Consideration all Employees nodes)
Please let me know if u have any questions

Below is the XML i have to transform:
<Company>
<Employees>
<employee >
<TypeCde>FN</TypeCde>
<salary>100000</salary>
</employee>
<employee>
<TypeCde>CL</TypeCde>
<salary>95000</salary>
</employee>
</Employees>
<Employees>
<employee>
<TypeCde>UH</TypeCde>
<salary>89000</salary>
</employee>
<employee>
<TypeCde>FN</TypeCde>
<salary>97000</salary>
</employee>
</Employees>
<Company>
Below is the xml i need after transformation


<Company>
<Employees>
<employee >
<TypeCde>FN</TypeCde>
<salary>100000</salary>
</employee>
<employee>
<TypeCde>CL</TypeCde>
<salary>95000</salary>
</employee>
<employee>
<TypeCde>UH</TypeCde>
<salary>89000</salary>
</employee>
</Employees>
</Comapny>


Thanks

Last edited by scubin : July 6th, 2009 at 05:09 PM.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!Reddit!
Reply With Quote
  #2 (permalink)  
Old July 6th, 2009, 05:31 PM
mhkay's Avatar
Wrox Author
Points: 12,642, Level: 48
Points: 12,642, Level: 48 Points: 12,642, Level: 48 Points: 12,642, Level: 48
Activity: 97%
Activity: 97% Activity: 97% Activity: 97%
 
Join Date: Apr 2004
Location: Reading, Berks, United Kingdom.
Posts: 3,900
Thanks: 0
Thanked 80 Times in 78 Posts
Default

First you have to group by typeCode - the way you do that depends greatly on whether it's XSLT 2.0 or 1.0. Then sort each group and take the first in descending order.

Code:
<xsl:for-each-group select="//employee" group-by="typeCode">
  <xsl:for-each select="current-group()">
     <xsl:sort select="xs:integer(salary)" order="descending"/>
     <xsl:if test="position() = 1">
        <xsl:copy-of select="."/>
     </xsl:if>
  </xsl:for-each>
</xsl:for-each-group>
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!Reddit!
Reply With Quote
  #3 (permalink)  
Old July 6th, 2009, 05:53 PM
Registered User
Points: 35, Level: 1
Points: 35, Level: 1 Points: 35, Level: 1 Points: 35, Level: 1
Activity: 8%
Activity: 8% Activity: 8% Activity: 8%
 
Join Date: Jul 2009
Posts: 9
Thanks: 0
Thanked 0 Times in 0 Posts
Default

I want it for XSLT version 1.0 ,seems <xsl:for-each group> is for version 2.0

can i know how to group by using version 1.o

Thanks fro quick reply
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!Reddit!
Reply With Quote
  #4 (permalink)  
Old July 6th, 2009, 06:52 PM
mhkay's Avatar
Wrox Author
Points: 12,642, Level: 48
Points: 12,642, Level: 48 Points: 12,642, Level: 48 Points: 12,642, Level: 48
Activity: 97%
Activity: 97% Activity: 97% Activity: 97%
 
Join Date: Apr 2004
Location: Reading, Berks, United Kingdom.
Posts: 3,900
Thanks: 0
Thanked 80 Times in 78 Posts
Default

Search for "Muenchian Grouping" in the index to your favourite XSLT textbook.
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!Reddit!
Reply With Quote
  #5 (permalink)  
Old July 7th, 2009, 02:32 AM
Registered User
Points: 35, Level: 1
Points: 35, Level: 1 Points: 35, Level: 1 Points: 35, Level: 1
Activity: 8%
Activity: 8% Activity: 8% Activity: 8%
 
Join Date: Jul 2009
Posts: 9
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Thank you Michael that helped a lot and i was able to get result what i want but there is one more thing that troubling me ,in the below XML if i want Employee Id to be outputted along with
Input XML:
<Company>
<Employees>
<Id>123</Id>
<employee >
<TypeCde>FN</TypeCde>
<salary>100000</salary>
</employee>
<employee>
<TypeCde>CL</TypeCde>
<salary>95000</salary>
</employee>
</Employees>
<Employees>
<Id>234</Id>
<employee>
<TypeCde>UH</TypeCde>
<salary>89000</salary>
</employee>
<employee>
<TypeCde>FN</TypeCde>
<salary>10000</salary>
</employee>
</Employees>
<Company>
Below is the my output should be

<Company>
<Employees>
<employee >
<TypeCde>FN</TypeCde>
<salary>100000</salary>
<Id>123</Id>
<Id>234</Id>
</employee>
<employee>
<TypeCde>CL</TypeCde>
<salary>95000</salary>
<Id>123</Id>
</employee>
<employee>
<TypeCde>UH</TypeCde>
<salary>89000</salary>
<Id>234</Id>
</employee>
</Employees>
</Comapny>

based on my muenchian method below is my code snippet
<xsl:for-each select="//employee[generate-id(.) = generate-id(key('k',
TypeCde)[1])]">
<xsl:for-each select="key('k', TypeCde)">
<xsl:sort select="salary" data-type="number" order="descending"/>
<xsl:if test="position() = 1">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
what can i do to get the <Id> of Employees in output xml?


Thnaks in advance
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!Reddit!
Reply With Quote
  #6 (permalink)  
Old July 7th, 2009, 04:40 AM
mhkay's Avatar
Wrox Author
Points: 12,642, Level: 48
Points: 12,642, Level: 48 Points: 12,642, Level: 48 Points: 12,642, Level: 48
Activity: 97%
Activity: 97% Activity: 97% Activity: 97%
 
Join Date: Apr 2004
Location: Reading, Berks, United Kingdom.
Posts: 3,900
Thanks: 0
Thanked 80 Times in 78 Posts
Default

Just replace the copy-of with an apply-templates select=".", and write a template rule for Employee something like

Code:
<xsl:template match="employee">
  <xsl:copy>
    <xsl:copy-of select="*"/>
    <xsl:copy-of select="../Id"/>
  </xsl:copy>
</xsl:template>
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!Reddit!
Reply With Quote
  #7 (permalink)  
Old July 7th, 2009, 08:49 AM
Registered User
Points: 35, Level: 1
Points: 35, Level: 1 Points: 35, Level: 1 Points: 35, Level: 1
Activity: 8%
Activity: 8% Activity: 8% Activity: 8%
 
Join Date: Jul 2009
Posts: 9
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Thank you very much michael for your reply but what i want is I need even the Emplotees Ids those having same salary in input XML also to be printed.The above code simply gives the first one that is having highest salary.If there are 2 or 3 Employee Ids having same highest salary I need those Employee Ids as well. Something like below .Can you tell me how to accomplish this
<Company>
<Employees>
<employee >
<TypeCde>FN</TypeCde>
<salary>1000</salary>
<Id>123</Id>
<Id>234</Id>
</employee>
<employee>
<TypeCde>CL</TypeCde>
<salary>95000</salary>
<Id>123</Id>
</employee>
<employee>
<TypeCde>UH</TypeCde>
<salary>89000</salary>
<Id>234</Id>
</employee>
</Employees>
</Comapny>

Thans a lot for your support
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!Reddit!
Reply With Quote
  #8 (permalink)  
Old July 7th, 2009, 08:57 AM
mhkay's Avatar
Wrox Author
Points: 12,642, Level: 48
Points: 12,642, Level: 48 Points: 12,642, Level: 48 Points: 12,642, Level: 48
Activity: 97%
Activity: 97% Activity: 97% Activity: 97%
 
Join Date: Apr 2004
Location: Reading, Berks, United Kingdom.
Posts: 3,900
Thanks: 0
Thanked 80 Times in 78 Posts
Default

Then you need to do a second level of grouping (group by salary) before you sort these groups on salary and choose the first; you then print the Ids for all the employees in the group.
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!Reddit!
Reply With Quote
  #9 (permalink)  
Old July 7th, 2009, 12:11 PM
Registered User
Points: 35, Level: 1
Points: 35, Level: 1 Points: 35, Level: 1 Points: 35, Level: 1
Activity: 8%
Activity: 8% Activity: 8% Activity: 8%
 
Join Date: Jul 2009
Posts: 9
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Iam sorry michael ,I couldnt figure out how to do that second level grouping

on salary,Iam getting lot of duplicates if iam doing 2 level grouping.Can you

help on this please

Thanks
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!Reddit!
Reply With Quote
  #10 (permalink)  
Old July 8th, 2009, 02:19 AM
Friend of Wrox
Points: 949, Level: 11
Points: 949, Level: 11 Points: 949, Level: 11 Points: 949, Level: 11
Activity: 31%
Activity: 31% Activity: 31% Activity: 31%
 
Join Date: Jun 2008
Location: Pondicherry, India
Posts: 205
Thanks: 9
Thanked 22 Times in 22 Posts
Thumbs up

Try this:

Code:
<xsl:key name="k" match="employee" use="TypeCde"/>

<xsl:template match="Company">
<xsl:copy>
<Employees>
<xsl:for-each select="//employee[generate-id(.) = generate-id(key('k',TypeCde)[1])]">
<xsl:for-each select="key('k', TypeCde)">
<xsl:sort select="salary" data-type="number" order="descending"/>
<xsl:if test="position() = 1">
<xsl:copy>
<xsl:variable name="type" select="TypeCde"></xsl:variable>
<xsl:variable name="sal" select="salary"></xsl:variable>
<xsl:copy-of select="$type"/>
<xsl:copy-of select="$sal"/>
<xsl:copy-of select="../Id"/>
<xsl:copy-of select="../..//Id[..//TypeCde = $type][not(..//salary = $sal)]"/>
</xsl:copy>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</Employees>
</xsl:copy>
</xsl:template>


There may be better solution from experts.
__________________
Rummy
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!Reddit!
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

vB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Adding and Sorting nodes georgemeng XSLT 4 December 1st, 2008 12:13 PM
Sorting some nodes by attribute value acw274 XSLT 8 July 2nd, 2008 02:22 AM
How to value in b/n nodes Swetha XSLT 1 May 20th, 2008 01:20 PM
Datagrid sorting by non alphabetical sorting? LLAndy VS.NET 2002/2003 1 July 15th, 2004 02:20 AM
HELP! More complicate sorting nodes question kevin_in_black XSLT 2 April 13th, 2004 06:51 AM



All times are GMT -4. The time now is 04:34 PM.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
© 2008 Wiley Publishing, Inc