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 February 22nd, 2012, 12:31 PM
Authorized User
 
Join Date: Sep 2008
Posts: 37
Thanks: 5
Thanked 0 Times in 0 Posts
Default

Hey Michael, I completely understanding your confusion. I actually reread my post and it looks like I mistakenly copied in the wrong name for the nodes in the "desired result"; it should have said "rank" node, not "top-player" node. I've updated all of my posts with code to reflect the proper names.

Regardless, let me break down the components of the object that you're confused about. So, for the rank node that I'm trying to create at the bottom of the file, here are the components:

Snippet of XML where the data is coming from for the first rank node:
Code:
   <pass y="500" t="1">
                <name value="mike"/>
                 <name-id id="1115"/>
   </pass>
Desired result:
Code:
<rank position="1" player-id="1115" name="mike" run-y="" run-t="" pass-y="500" pass-t="1" receive-y="" receive-t=""/>
position => position()
id => name-id/@id
name =>name/@value
pass-y => pass/@y
pass-t => pass/@t

Now, the reason the desired result above is output as rank 1 is because based off of my sort logic algorithm:

Code:
<xsl:sort select="(run/@y * 1 + run/@t * 10 + pass/@y * .5 + pass/@t * 5 + receive/@y * .5 + receive/@t * 5)" data-type="number" order="descending"/>
The rank node gets evaluated to the first position because of the following:
pass/@y = (500*.5) + (pass/@t = 1 * 5) = 255

Now, for the rank node at position 2 it would be: receive/@y = (322*.5) + (receive/@t = 1 * 5) = 166

Data in the original XML for position 2
Code:
  <receive y="322" t="1">
                <name value="greg"/>
                 <name-id id="1205"/>
    </receive >
Desired results for position2:
Code:
<rank position="2" player-id="1205" name="greg" run-y="" run-t="" pass-y="" pass-t="" receive-y="322" receive-t="1"/>
I'm basically just trying to parse the entire XML and return the top three nodes/child-nodes that have the highest value based of on the sort logic specified above.

Last edited by vb89; February 22nd, 2012 at 12:33 PM..
 
Old February 22nd, 2012, 05:32 PM
samjudson's Avatar
Friend of Wrox
 
Join Date: Aug 2007
Posts: 2,128
Thanks: 1
Thanked 189 Times in 188 Posts
Default

In your xsl:for-each statement you are using "//sub-rot/*/*" as your select statement. Therefore inside the loop the current context will be either a run element, a pass element, or a receive element.

Trying to then sort on "run/@y" is looking for a sub-element of one of these called run, which doesn't exist. If you do self::run/@y it will select the @y attribute if the current element is a <run> element, but will still return nothing for the other element types.

Finally, adding self::run/@y + self::pass/@y will always equal "NaN", as the current element will never be both a run and a pass.

In XSLT 1.0 I'm afraid I don't know how to do this kind of sort.

In XSLT 2.0 it is possible using XPath conditional expressions like so:

Code:
	<xsl:for-each select="//sub-root/*/*">
		<xsl:sort select="if (self::run) then @y * 1 + @t * 10 else if (self::pass) then @y * .5 + @t * 5 else @y * .5 + @t * 5" data-type="number" order="descending"/>
			<xsl:if test="position() &lt; 4">					
					<xsl:variable name="nCode" select="name-id/@id"/>
					<xsl:variable name="name"  select="name/@value"/>
					<xsl:variable name="ry"  select="self::run/@y"/>
					<xsl:variable name="rt"  select="self::run/@t"/>
					<xsl:variable name="py"  select="self::pass/@y"/>
					<xsl:variable name="pt"  select="self::pass/@t"/>
					<xsl:variable name="recy"  select="self::receive/@y"/>
					<xsl:variable name="rect"  select="self::receive/@t"/>
					<top-player rank="{position()}" id="{$nCode}" first="{$name}" pass-yards="{$py}" pass-tds="{$pt}" rush-yards="{$ry}" rush-tds="{$rt}" rec-yards="{$recy}" rec-tds="{$recy}"/>
					
			</xsl:if>
	</xsl:for-each>
__________________
/- Sam Judson : Wrox Technical Editor -/

Think before you post: What have you tried?
The Following User Says Thank You to samjudson For This Useful Post:
vb89 (February 22nd, 2012)





Similar Threads
Thread Thread Starter Forum Replies Last Post
Simple sorting issue dcschafer XSLT 1 August 4th, 2009 07:45 AM
sorting issue nguna XSLT 3 July 28th, 2009 07:45 AM
sorting issue JohnBampton XSLT 10 February 23rd, 2009 08:13 AM
sorting issue moin.khan Struts 0 June 21st, 2007 09:37 AM
Sorting in XSLT hchaudh1 XSLT 1 November 30th, 2005 05:37 AM





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