xsl-list
[Top] [All Lists]

Re: [xsl] How to dynamically evaluate an equation in the input XML document?

2021-07-15 01:04:55
On Thu, Jul 15, 2021 at 12:18 AM Roger L Costello costello(_at_)mitre(_dot_)org 
<
xsl-list-service(_at_)lists(_dot_)mulberrytech(_dot_)com> wrote:


I have XML documents like this:

<Convert-to-Celsius>
    <equation>(Fahrenheit - 32) * (5/9)</equation>
    <variable>
        <name>Fahrenheit</name>
        <value>32</value>
    </variable>
</Convert-to-Celsius>

The document contains an equation which might contain variables. If it
does contain variables, then I need to fetch their values and replace the
variables in the equation with their values and then compute the value of
the equation.

Have you done this kind of dynamic equation solving using XSLT? If so, how
did you do it?


In an XSLT 2.0 environment with Saxon, I've attempted to do this as
following (examples that I've run are cited),

XSLT stylesheet,

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                         xmlns:xs="http://www.w3.org/2001/XMLSchema";

                         xmlns:saxon="http://saxon.sf.net/";
                         xmlns:fn1="http://fn1";
                         exclude-result-prefixes="xs saxon fn1"
                         version="2.0">

   <xsl:output method="text"/>

   <xsl:template match="Input">
     <xsl:value-of
select="saxon:evaluate(fn1:constructFinalExpression(equation,
variable[1]))"/>
   </xsl:template>

   <xsl:function name="fn1:constructFinalExpression" as="xs:string">
      <xsl:param name="equation" as="xs:string"/>
      <xsl:param name="variable" as="element(variable)"/>

      <xsl:choose>
        <xsl:when test="$variable/following-sibling::variable">
           <xsl:sequence select="fn1:constructFinalExpression(
                                          replace($equation,
$variable/name, $variable/value),

$variable/following-sibling::variable[1])"/>
        </xsl:when>
        <xsl:otherwise>
           <xsl:sequence select="replace($equation, $variable/name,
$variable/value)"/>
        </xsl:otherwise>
      </xsl:choose>
   </xsl:function>

</xsl:stylesheet>

1) XML document input,

<Input>
  <equation>(Fahrenheit - 32) * (5 div 9)</equation>
  <variable>
    <name>Fahrenheit</name>
    <value>32</value>
  </variable>
</Input>

Transformation result,

0

2) XML document input,

<Input>
  <equation>(x + 5) * (y + 5) * z</equation>
  <variable>
    <name>x</name>
    <value>2</value>
  </variable>
  <variable>
    <name>y</name>
    <value>3</value>
  </variable>
  <variable>
    <name>z</name>
    <value>2</value>
  </variable>
</Input>

Transformation result,

112


I've observed that, for example, if the input equation contains the
division operator as '/' instead of 'div' (as in XPath), Saxon gives me
following errors,

XPTY0019: Required item type of first operand of '/' is node(); supplied
value has item type xs:integer



-- 
Regards,
Mukul Gandhi
--~----------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
EasyUnsubscribe: http://lists.mulberrytech.com/unsub/xsl-list/1167547
or by email: xsl-list-unsub(_at_)lists(_dot_)mulberrytech(_dot_)com
--~--
<Prev in Thread] Current Thread [Next in Thread>