tags:

views:

32

answers:

1

There is probably a very easy solution for this problem. I could easily do this in C#-LINQ. Unfortunately, I'm not so experienced with XPath and XSL.

I have an input XML file that contains the following structure:

<group>
    <val>1</val>
    <val>3</val>
    <val>1</val>
</group>
<group>
    <val>3</val>
    <val>2</val>
    <val>2</val>
</group>

Now in my XSL transform I want to define 1 variable "highestsum", which contains the highest sum of 'values'. So for the example, it would return 7, the sum of all values in the second group.

After some searching, this is the closest solution I found:

http://w3schools.invisionzone.com/index.php?showtopic=24265

But I have a feeling that there's a better way than using sorting in a template to achieve this result. Any takers?

+2  A: 

I. A good XSLT 1.0 solution (brief, efficient and understandable):

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
 <xsl:output method="text"/>

 <xsl:template match="/*">
   <xsl:for-each select="group">
     <xsl:sort select="sum(val)" data-type="number"
      order="descending"/>

     <xsl:if test="position()=1">
       <xsl:value-of select="sum(val)"/>
     </xsl:if>
   </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

when this transformation is applied on the following XML document:

<t>
    <group>
        <val>1</val>
        <val>3</val>
        <val>1</val>
    </group>
    <group>
        <val>3</val>
        <val>2</val>
        <val>2</val>
    </group>
</t>

the wanted, correct result is produced:

7

To get the desired variable definition, simply put the <xsl:for-each> instruvtion from the above code in the body of the variable.

II. An even better XSLT 2.0 (and actually XPath 2.0 one-liner) solution:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
 <xsl:output method="text"/>

 <xsl:template match="/*">
   <xsl:sequence select="max(group/sum(val))"/>
 </xsl:template>
</xsl:stylesheet>

when this transformation is applied on the same XML document, the same correct answer is produced:

7

And the wanted variable definition is simply:

  <xsl:variable name="vHighestSum" 
       select="max(group/sum(val))"/>

Finally, the same Xpath expression can be used in XQuery to define the required variable:

let $vHighestSum := max(/*/group/sum(val))
Dimitre Novatchev
Thanks for the very complete answer. The Xpath one-liner worked great, however I found out I can't use this more elegant syntax because (if I understood correctly) .NET does not currently support this.So I used your XSLT 1.0 solution, which works fine as well. Thanks a lot!
Bram De Moor