[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Getting average

Subject: Re: Getting average
From: David Carlisle <davidc@xxxxxxxxx>
Date: Tue, 27 May 2008 22:48:59 +0100
Re:  Getting average
>  I am using XSLT 1.0.
shame as it's _much_ easier in xslt2, as single function call:

>  A double pass is not practical.
why not? doing two passes would be by far the easiest way in xslt 1.
Can you not use a x:node-set() extension function to make this

If neither is possible you have to do a recursive walk over the tree.

> I have an XML file in the following format:
It helps if the samples are well formed, then anyone trying a solution
will use the same data.

here's a well formed input and a stylesheet that demonstrates the three
possible solution styles (written as xslt2 but the second will run in
xslt1 if you supply the appropriate namespace for the node-set
extension, and the third solution would run unchanged in xslt1

	<group income="1000">
		<person age="10"/>
		<person age="15"/>
		<person age="30"/>

	<group income="2000">
		<person age="10"/>
		<person age="40"/>
	<group income="5000">
		<person age="20"/>
		<person age="20"/>

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:x="data:,x">
<xsl:param name="age" select="10"/>

<xsl:function name="x:node-set">
 <xsl:param name="n"/>
 <xsl:sequence select="$n"/>

<xsl:template match="/">

 <xsl:text>&#10; xslt2            : </xsl:text>
 <xsl:value-of select="avg(for $p in customers/group/person[@age=$age] return $p/../@income)"/>

 <xsl:text>&#10; xslt1 (node set) : </xsl:text>
 <xsl:variable name="x">
  <xsl:for-each select="customers/group/person[@age=$age]">
    <i><xsl:value-of select="../@income"/></i>
<xsl:value-of select="sum(x:node-set($x)/i) div count(x:node-set($x)/i)"/>

 <xsl:text>&#10; xslt 1 (one pass): </xsl:text>
 <xsl:apply-templates select="(customers/group/person[@age=$age])[1]" mode="avg"/>

<xsl:template match="person" mode="avg">
<xsl:param name="s" select="0"/>
<xsl:param name="c" select="0"/>
<xsl:variable name="n" select="following::person[@age=$age][1]"/>
 <xsl:when test="$n">
  <xsl:apply-templates select="$n" mode="avg">
   <xsl:with-param name="s" select="$s + ../@income"/>
   <xsl:with-param name="c" select="$c + 1"/>
  <xsl:value-of select="($s + ../@income) div ($c + 1)"/>

$ saxon9 avg.xml avg.xsl age=10
<?xml version="1.0" encoding="UTF-8"?>
 xslt2            : 1500
 xslt1 (node set) : 1500
 xslt 1 (one pass): 1500

$ saxon9 avg.xml avg.xsl age=20
<?xml version="1.0" encoding="UTF-8"?>
 xslt2            : 5000
 xslt1 (node set) : 5000
 xslt 1 (one pass): 5000

The Numerical Algorithms Group Ltd is a company registered in England
and Wales with company number 1249803. The registered office is:
Wilkinson House, Jordan Hill Road, Oxford OX2 8DR, United Kingdom.

This e-mail has been scanned for all viruses by Star. The service is
powered by MessageLabs. 

Current Thread


Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
First Name
Last Name
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.