Can I do element division in XSLT?

I have a data structure that looks something like this:

<resultSet> <result> <numCorrect>1</numCorrect> <truthCorrect>4</truthCorrect> </result> <result> <numCorrect>2</numCorrect> <truthCorrect>4</truthCorrect> </result> <result> <numCorrect>3</numCorrect> <truthCorrect>5</truthCorrect> </result> <result> <numCorrect>5</numCorrect> <truthCorrect>6</truthCorrect> </result> </resultSet> 

I would like to compute avg((result/numCorrect) div (result/truthCorrect)) , but XSLT doesn't seem to allow elementary division, how can I calculate this average?

If this helps, I use Saxon as an XSLT 2.0 processor.

+4
source share
2 answers

The following will do what you want.

It uses recursion and sequentially adds all paired calculations, and in the end it divides by the number of results.

 <xsl:template match = "/resultSet" > <xsl:variable name="TotalSum"> <xsl:call-template name="calculator"> <xsl:with-param name="currSum">0</xsl:with-param> <xsl:with-param name="count"><xsl:value-of select="count(result)"/></xsl:with-param> </xsl:call-template> </xsl:variable> <xsl:value-of select="$TotalSum div count(result)"/> </xsl:template> <xsl:template name="calculator"> <xsl:param name="currSum"/> <xsl:param name="count"/> <xsl:variable name="actual" select="number(result[number($count)]/numCorrect)"/> <xsl:variable name="truth" select="number(result[number($count)]/truthCorrect)"/> <xsl:variable name="singleResult" select="number($actual div $truth)"/> <xsl:variable name="CycleSum" select="number($currSum + $singleResult)"/> <xsl:choose> <xsl:when test="number($count - 1) > 0 "> <xsl:call-template name="calculator"> <xsl:with-param name="currSum"><xsl:value-of select="$CycleSum"/></xsl:with-param> <xsl:with-param name="count"><xsl:value-of select="number($count - 1)"/></xsl:with-param> </xsl:call-template> </xsl:when> <xsl:otherwise><xsl:value-of select="$CycleSum"/></xsl:otherwise> </xsl:choose> </xsl:template> 

Let me know if there are parts you don’t understand.

+3
source

The short-term solution that works seems to be this:

 <?xml version="1.0" encoding="UTF-8" ?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exslt="http://exslt.org/common"> <xsl:template match="/resultSet"> <xsl:variable name="foo"> <xsl:for-each select="result"> <n><xsl:value-of select="numCorrect div truthCorrect" /></n> </xsl:for-each> </xsl:variable> <xsl:value-of select="avg(exslt:node-set($foo)/n)" /> </xsl:template> </xsl:stylesheet> 

where <xsl:value-of select="avg(exslt:node-set($foo)/n)" /> can be replaced by

 <xsl:value-of select="sum(exslt:node-set($foo)/n) div count(result)" /> 

if you are using an XSLT engine that supports exslt extensions but does not have the non-standard avg function.

0
source

Source: https://habr.com/ru/post/1300901/


All Articles