我想在 xslt 文件中做一些计算,并且需要在公式中做一些平方根。有人可以指出是否可能以及如何请?
感谢磨坊
可以使用FXSLsqrt
的模板/功能:
一、在 XSLT 1.0 中:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:import href="sqrt.xsl"/>
<!-- To be applied on any source xml.
This also tests the within() function
-->
<xsl:output indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="/">
sqrt(0.25):
<xsl:call-template name="sqrt">
<xsl:with-param name="N" select="0.25"/>
<xsl:with-param name="Eps" select="0.00001"/>
</xsl:call-template>
sqrt(1):
<xsl:call-template name="sqrt">
<xsl:with-param name="N" select="1"/>
<xsl:with-param name="Eps" select="0.00001"/>
</xsl:call-template>
sqrt(2):
<xsl:call-template name="sqrt">
<xsl:with-param name="N" select="2"/>
<xsl:with-param name="Eps" select="0.00001"/>
</xsl:call-template>
sqrt(9):
<xsl:call-template name="sqrt">
<xsl:with-param name="N" select="9"/>
<xsl:with-param name="Eps" select="0.00001"/>
</xsl:call-template>
sqrt(16):
<xsl:call-template name="sqrt">
<xsl:with-param name="N" select="16"/>
<xsl:with-param name="Eps" select="0.00001"/>
</xsl:call-template>
sqrt(25):
<xsl:call-template name="sqrt">
<xsl:with-param name="N" select="25"/>
<xsl:with-param name="Eps" select="0.00001"/>
</xsl:call-template>
sqrt(36):
<xsl:call-template name="sqrt">
<xsl:with-param name="N" select="36"/>
<xsl:with-param name="Eps" select="0.00001"/>
</xsl:call-template>
sqrt(49):
<xsl:call-template name="sqrt">
<xsl:with-param name="N" select="49"/>
<xsl:with-param name="Eps" select="0.00001"/>
</xsl:call-template>
sqrt(64):
<xsl:call-template name="sqrt">
<xsl:with-param name="N" select="64"/>
<xsl:with-param name="Eps" select="0.00001"/>
</xsl:call-template>
sqrt(81):
<xsl:call-template name="sqrt">
<xsl:with-param name="N" select="81"/>
<xsl:with-param name="Eps" select="0.00001"/>
</xsl:call-template>
sqrt(100):
<xsl:call-template name="sqrt">
<xsl:with-param name="N" select="100"/>
<xsl:with-param name="Eps" select="0.00001"/>
</xsl:call-template>
sqrt(121):
<xsl:call-template name="sqrt">
<xsl:with-param name="N" select="121"/>
<xsl:with-param name="Eps" select="0.00001"/>
</xsl:call-template>
</xsl:template>
</xsl:stylesheet>
当将此转换应用于任何 XML 文档(未使用)时,将产生所需的正确结果:
sqrt(0.25):
0.5000000795866174
sqrt(1):
1.0000000464611474
sqrt(2):
1.4142156862745097
sqrt(9):
3.0000000000393214
sqrt(16):
4.0000001858445895
sqrt(25):
5.000000000016778
sqrt(36):
6.000000002793968
sqrt(49):
7.000000094930961
sqrt(64):
8.000001273385879
sqrt(81):
9.000009415515176
sqrt(100):
10.000000000107445
sqrt(121):
11.000000001323027
二、将 FXSL 2.x 用于 XSLT 2.0:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="http://fxsl.sf.net/">
<xsl:import href="../f/func-sqrt.xsl"/>
<xsl:import href="../f/func-map.xsl"/>
<xsl:import href="../f/func-standardXpathFunctions.xsl"/>
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:value-of separator="
" select=
"f:map(f:round-half-to-even(f:sqrt(2, 0.000001)),
0 to 13
)
"/>
</xsl:template>
</xsl:stylesheet>
当将此转换应用于任何 XML 文档(未使用)时,将产生所需的正确结果:
1
1.4
1.41
1.414
1.4142
1.41421
1.414214
1.4142136
1.41421356
1.414213562
1.4142135624
1.41421356237
1.414213562375
1.4142135623747
如果您使用的是 XSLT 2.0,则问题已排序——请参阅 Dimitre 的回答。如果您使用的是 XSLT 1.0,实际上在生产环境中,我仍然会选择 Dimitre 的答案。在商业上,最好使用经过测试的库而不是重新发明轮子。
但是,我认为您的问题实施独立解决方案可能会很有趣。它是!
给定这一堆值来找到...的根源
<squares>
<square>0</square>
<square>0.25</square>
<square>1</square>
<square>9</square>
<square>10</square>
</squares>
...当输入到此 XSLT 1.0 样式表时...
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:variable name="verysmall" select="0.00001" />
<xsl:template match="/">
<roots>
<xsl:apply-templates select="*/square"/>
</roots>
</xsl:template>
<xsl:template match="square">
<root>
<xsl:call-template name="root">
<xsl:with-param name="x" select="." />
</xsl:call-template>
</root>
</xsl:template>
<xsl:template name="root">
<xsl:param name="x"/><!-- Assume x >= 0 -->
<xsl:choose>
<xsl:when test="$x > 1">
<xsl:call-template name="iterate-root">
<xsl:with-param name="x" select="$x" />
<xsl:with-param name="H" select="$x" />
<xsl:with-param name="L" select="0" />
</xsl:call-template>
</xsl:when>
<xsl:when test="($x = 1) or ($x <= 0)">
<xsl:value-of select="$x" />
</xsl:when>
<xsl:otherwise>
<xsl:variable name="inv-root">
<xsl:call-template name="iterate-root">
<xsl:with-param name="x" select="1 div $x" />
<xsl:with-param name="H" select="1 div $x" />
<xsl:with-param name="L" select="0" />
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="1 div $inv-root" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="iterate-root">
<xsl:param name="x"/> <!-- Assume x > 1 -->
<xsl:param name="H"/> <!-- High estimate -->
<xsl:param name="L"/> <!-- Low estimate -->
<xsl:variable name="M" select="($H + $L) div 2" />
<xsl:variable name="g" select="($M * $M - $x) div $x" />
<xsl:choose>
<xsl:when test="(($g < $verysmall) and ((- $g) < $verysmall)) or
(($H - $L) < $verysmall)">
<xsl:value-of select="$M"/>
</xsl:when>
<xsl:when test="$g > 0">
<xsl:call-template name="iterate-root">
<xsl:with-param name="x" select="$x" />
<xsl:with-param name="H" select="$M" />
<xsl:with-param name="L" select="$L" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="iterate-root">
<xsl:with-param name="x" select="$x" />
<xsl:with-param name="H" select="$H" />
<xsl:with-param name="L" select="$M" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
...产生近似解...
<roots>
<root>0</root>
<root>0.5</root>
<root>1</root>
<root>2.999988555908203</root>
<root>3.1622695922851562</root>
</roots>
该技术使用分而治之来找到方程 f(y) = y*y - x 的根,它出现在 x 的平方根处。该技术可能仅对实现优化的尾端递归的 XSLT 处理器相当有效。