XSLT整数计算器,如何实现n元求和和和乘法?
我正在尝试实现一个小的整数计算器。实际上,它处理的xml文档有一个表达式和一个XSLT整数计算器,如何实现n元求和和和乘法?,xslt,integer,xslt-2.0,evaluation,Xslt,Integer,Xslt 2.0,Evaluation,我正在尝试实现一个小的整数计算器。实际上,它处理的xml文档有一个表达式和一个varDef列表,其中包含可能变量的值 XSLT将该XML文档转换为另一个文档并生成结果 这是XML文档的XML模式: <?xml version="1.0" encoding="UTF-8"?> <schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:ej3="http://procesadores.ejemplo.com/Ej3"
varDef
列表,其中包含可能变量的值
XSLT将该XML文档转换为另一个文档并生成结果
这是XML文档的XML模式:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:ej3="http://procesadores.ejemplo.com/Ej3"
targetNamespace="http://procesadores.ejemplo.com/Ej3"
elementFormDefault="qualified">
<element name="documento">
<complexType>
<sequence>
<element ref="ej3:expr"/>
<element ref="ej3:varDef" maxOccurs="unbounded" minOccurs="0"/>
</sequence>
</complexType>
</element>
<element name="expr" abstract="true"/>
<element name="suma" type="ej3:expBinaria" substitutionGroup="ej3:expr"/>
<element name="resta" type="ej3:expBinaria" substitutionGroup="ej3:expr"/>
<element name="mult" type="ej3:expBinaria" substitutionGroup="ej3:expr"/>
<element name="div" type="ej3:expBinaria" substitutionGroup="ej3:expr"/>
<element name="mod" type="ej3:expBinaria" substitutionGroup="ej3:expr"/>
<element name="opuesto" type="ej3:expUnaria" substitutionGroup="ej3:expr"/>
<element name="abs" type="ej3:expUnaria" substitutionGroup="ej3:expr"/>
<element name="var" type="ej3:tipoNombreVar" substitutionGroup="ej3:expr"/>
<element name="cons" type="integer" substitutionGroup="ej3:expr"/>
<element name="varDef">
<complexType>
<simpleContent>
<extension base="int">
<attribute name="nombre" type="ej3:tipoNombreVar"/>
</extension>
</simpleContent>
</complexType>
</element>
<complexType name="expUnaria">
<sequence>
<element ref="ej3:expr" minOccurs="1" maxOccurs="1"/>
</sequence>
</complexType>
<complexType name="expBinaria">
<sequence>
<element ref="ej3:expr" minOccurs="2" maxOccurs="2"/>
</sequence>
</complexType>
<complexType name="expNaria">
<sequence>
<element ref="ej3:expr" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
</complexType>
<simpleType name="tipoNombreVar">
<restriction base="string">
<pattern value="[a-zA-Z][a-zA-Z0-9]*"/>
</restriction>
</simpleType>
</schema>
应该能够被评估。为了让它工作,我必须修改suma
xsl:template,但我不太确定如何做。我尝试了很多方法,但在把孩子们相加之前,我必须对他们进行评估,这让我很难找到解决办法
你能建议如何做到这一点吗
请注意,我希望
sum
和mult
操作数都以这种方式工作,因此基于xpath函数sum()
的解决方案将不适用于mult
我将确保模板返回xs:integer
的序列,例如change
<xsl:template match="ej3:cons">
<test><xsl:value-of select="."/></test>
</xsl:template>
然后把它用在
<xsl:template match="multa">
<xsl:variable name="operands" as="xs:integer+">
<xsl:apply-templates select="*"/>
</xsl:variable>
<xsl:sequence select="mf:multiply($operands)"/>
</xsl:template>
以下是一个例子:
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="xs mf">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:function name="mf:multiply" as="xs:integer">
<xsl:param name="operands" as="xs:integer+"/>
<xsl:sequence select="if (not(exists($operands[2])))
then $operands[1]
else $operands[1] * mf:multiply($operands[position() gt 1])"/>
</xsl:function>
<xsl:template match="expression">
<result>
<xsl:apply-templates/>
</result>
</xsl:template>
<xsl:template match="cons">
<xsl:sequence select="xs:integer(.)"/>
</xsl:template>
<xsl:template match="suma">
<xsl:variable name="operands" as="xs:integer+">
<xsl:apply-templates select="*"/>
</xsl:variable>
<xsl:sequence select="sum($operands)"/>
</xsl:template>
<xsl:template match="multa">
<xsl:variable name="operands" as="xs:integer+">
<xsl:apply-templates select="*"/>
</xsl:variable>
<xsl:sequence select="mf:multiply($operands)"/>
</xsl:template>
</xsl:stylesheet>
示例输入为
<expression>
<suma>
<cons>1</cons>
<cons>2</cons>
<cons>3</cons>
<multa>
<cons>1</cons>
<cons>2</cons>
<cons>3</cons>
</multa>
</suma>
</expression>
1.
2.
3.
1.
2.
3.
我得到了输出
12
如何使用该方法实现n元乘法?@Trollkemada,我对答案进行了编辑,并提出了一些建议,应该有助于实现它,尽管未经测试,并且仅在SO编辑器中直接键入。mult和sum都将结果连接为字符串,这就是我所有努力的问题所在。我在一些在线xslt测试人员中进行了测试,得到了相同的结果。@Trollkemada,我做了一些编辑,并添加了一个简短但完整的示例来完成这项工作。如果仍然存在问题,请编辑问题并提供一些示例表达式的XML输入文档。请注意,使用xsl:sequence
而不是xsl:value of
是必不可少的。
<xsl:template match="suma">
<xsl:variable name="operands" as="xs:integer+">
<xsl:apply-templates select="*"/>
</xsl:variable>
<xsl:sequence select="sum($operands)"/>
</xsl:template>
<xsl:function name="mf:multiply" as="xs:integer">
<xsl:param name="operands" as="xs:integer+"/>
<xsl:sequence select="if (not(exists($operands[2])))
then $operands[1]
else $operands[1] * mf:multiply($operands[position() gt 1])"/>
</xsl:function>
<xsl:template match="multa">
<xsl:variable name="operands" as="xs:integer+">
<xsl:apply-templates select="*"/>
</xsl:variable>
<xsl:sequence select="mf:multiply($operands)"/>
</xsl:template>
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="xs mf">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:function name="mf:multiply" as="xs:integer">
<xsl:param name="operands" as="xs:integer+"/>
<xsl:sequence select="if (not(exists($operands[2])))
then $operands[1]
else $operands[1] * mf:multiply($operands[position() gt 1])"/>
</xsl:function>
<xsl:template match="expression">
<result>
<xsl:apply-templates/>
</result>
</xsl:template>
<xsl:template match="cons">
<xsl:sequence select="xs:integer(.)"/>
</xsl:template>
<xsl:template match="suma">
<xsl:variable name="operands" as="xs:integer+">
<xsl:apply-templates select="*"/>
</xsl:variable>
<xsl:sequence select="sum($operands)"/>
</xsl:template>
<xsl:template match="multa">
<xsl:variable name="operands" as="xs:integer+">
<xsl:apply-templates select="*"/>
</xsl:variable>
<xsl:sequence select="mf:multiply($operands)"/>
</xsl:template>
</xsl:stylesheet>
<expression>
<suma>
<cons>1</cons>
<cons>2</cons>
<cons>3</cons>
<multa>
<cons>1</cons>
<cons>2</cons>
<cons>3</cons>
</multa>
</suma>
</expression>