XSLT - Loop through unknown node names

My XSLT/XPATH is a bit rusty. The sample xml contains several <price> elements and I  need to figure out how sum up these values, but only the CHEAPEST of each service type.
 
So far, i've done this:

<xsl:for-each select="AvailabilitySearch/Services">
      <xsl:value-of select="sum(child::*/child::*/child::Price)"/>
</xsl:for-each>

This gets me the sum of all the price elements. However, I need to extend this to:
1/ Only Sum up the cheapest of each service i.e. the cheapest book, the cheapest cd, the chepest game
2/ Be able to skip a specified service e.g. Don't include the Books in the calculation, only sum up the cheapest cd and game.

To be able to sum up only the cheapest, i'm guessing that I should be doing a sort. As a test, I tried this:
<xsl:for-each select="child::*/child::*">
            <xsl:sort data-type="number" order="ascending" select="Price"/>
      <xsl:value-of select="Price"/>
      <br/>
</xsl:for-each>

However this sorts the WHOLE of the results by price, rather than the services individually.

Any help would be great. If anything isn't clear please let me know and i'll try and explain further.

Thanks.
<AvailabilitySearch>
	<Services>
		<Books>
			<Book id="1">
				<Name>Book 1</Name>
				<Code>1234</Code>
				<Price>10</Price>
			</Book>
			<Book id="1">
				<Name>Book 1</Name>
				<Code>5678</Code>
				<Price>20</Price>
			</Book>
		</Books>
		<CDS>
			<CD>
				<Name>CD 1</Name>
				<Code>9101112</Code>
				<Price>5</Price>
			</CD>
			<CD>
				<Name>CD 2</Name>
				<Code>13141516</Code>
				<Price>7</Price>
			</CD>
		</CDS>
                                           <Games>
			<Game>
				<Name>Game 1</Name>
				<Price>39.99</Price>
			</Game>
			<Game>
				<Name>Game 2</Name>
				<Price>42.99</Price>
			</Game>
			<Game>
				<Name>Game 3</Name>
				<Price>24.99</Price>
			</Game>
		</Games>
	</Services>
</AvailabilitySearch>

Open in new window

LVL 1
hendrix500Asked:
Who is Participating?
 
Geert BormansConnect With a Mentor Information ArchitectCommented:
excluding books
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template match="Services">
        <xsl:value-of select="sum(*[not(self::Books)]/*[not(Price > preceding-sibling::*/Price)][not(Price > following-sibling::*/Price)][1]/Price)"/>
     </xsl:template>
</xsl:stylesheet>

Open in new window

0
 
Geert BormansConnect With a Mentor Information ArchitectCommented:
Here is how to loop only the cheapest in their kind
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template match="Services">
        <xsl:for-each select="*/*[not(Price > preceding-sibling::*/Price)][not(Price > following-sibling::*/Price)][1]">
            <xsl:copy-of select="."/>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

Open in new window

0
 
Geert BormansConnect With a Mentor Information ArchitectCommented:
Here is your sum
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template match="Services">
        <xsl:value-of select="sum(*/*[not(Price > preceding-sibling::*/Price)][not(Price > following-sibling::*/Price)][1]/Price)"/>
     </xsl:template>
</xsl:stylesheet>

Open in new window

0
 
hendrix500Author Commented:
Perfect. Thanks for your quick answer.
0
 
Geert BormansInformation ArchitectCommented:
welcome
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.