0

我需要用 xml 和 xslt 编写符号导数。所以我在 xml 中创建了一个数学函数树,xslt 必须派生函数的每个表达式。例如:“y = 2x^2 + 3x^5” 所以“dy/dx= (2*2)x^(2-1) + (3*5)^(5-1) = 4x + 15x^4 " 和 xml 会是这样的:

<function>
    <expression>
        <coefficient>2</coefficient>
        <variable>x</variable>
        <exponent>2</exponent>
        <sign>+</sign> <!-- Sign operating with the next expression (+,-,x,/) -->
    </expression>
    <expression>
        <coefficient>3</coefficient>
        <variable>x</variable>
        <exponent>5</exponent>
        <sign></sign>
    </expression>
</function>

我遇到的问题是我想在 xslt 中声明一个变量 i 所以当 expression[i]/sign="+" 它执行链式规则并且 i=i+1 所以它转到下一个表达式时,我可以这样做使用 a for-each,但是当 expression[i]/sign="x" 我需要执行乘积规则并跳转两步所以 i=i+2,因为如果 i=3 则 "expression[3] x expression[4]" ,所以我不想再推导表达式[4]。那么我怎么能用 xslt 做到这一点,因为我不能修改变量的值呢?如果我想表达 4x^3(5x^2+2x^7) 那么我必须改变我的 xml 结构,怎么可能是 xslt 代码?

4

1 回答 1

0

我假设 XSLT 2.0。如果不是,请告诉我。

此样式表仅适用于二项式表达式,并且仅适用于符号值“+”或“-”。

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="2.0">

<xsl:output omit-xml-declaration="yes" encoding="UTF-8"/>  
  <xsl:strip-space elements="*" /> 

<xsl:template match="function">
  <xsl:copy>
    <xsl:variable name="expressions" as="element(expression)*">
      <xsl:apply-templates select="expression" mode="differentiate"/>
    </xsl:variable>
    <xsl:for-each-group select="$expressions" group-by="concat(variable,'^',exponent)">
      <xsl:sort select="exponent" data-type="number" order="ascending" />
      <expression>
        <xsl:variable name="signed-coefficient" select="sum(coefficient)" />
        <coefficient><xsl:value-of select="abs( $signed-coefficient)" /></coefficient>
        <variable><xsl:value-of select="current-group()[1]/variable" /></variable>
        <exponent><xsl:value-of select="current-group()[1]/exponent" /></exponent>
        <sign><xsl:value-of select="if ($signed-coefficient ge 0) then '+' else '-'" /></sign>
      </expression> 
    </xsl:for-each-group>
  </xsl:copy>
</xsl:template>

<xsl:template match="expression" mode="differentiate">
  <xsl:copy>
    <coefficient><xsl:value-of select="
      for $x in coefficient * exponent return
        if (sign = '-') then - $x
                        else   $x" /></coefficient>
    <variable><xsl:value-of select="variable" /></variable>
    <exponent><xsl:value-of select="exponent - 1" /></exponent>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>

您可以通过添加模板轻松扩展此解决方案以包含其他形式的表达式(和其他符号值),每个模板处理不同的微分规则(例如链规则、乘积规则等)

于 2015-08-13T02:03:11.703 回答