如何用 XML 和 XSLT 做一个计算器

E. 威廉姆斯

我正在使用XSDXMLXSLT构建表达式计算器

目前只Sum执行操作。

我已经开发了xml-schema一个有效的xml文件。

架构 (XSD)

<xs:complexType name="typeSum">
        <xs:sequence>
            <xs:element ref="exp:Expression"/>
            <xs:element ref="exp:Expression"/>
        </xs:sequence>
    </xs:complexType>

<xs:complexType name="EE">
    <xs:sequence>
        <xs:element ref="exp:Expression" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
</xs:complexType>

<xs:element name="Expression" abstract="true"/>
<xs:element name="EE" type="exp:EE"/>
<xs:element name="Const" type="xs:integer" substitutionGroup="exp:Expression"/>
<xs:element name="Sum" type="exp:typeSum" substitutionGroup="exp:Expression"/>

XML(在这个XML我想做到以下几点:Sum(Sum(8,4),Sum(1,2))

<?xml version="1.0" encoding="UTF-8"?>
<e:EE xmlns:e="expr"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="xxx/xxx/xxx...">
    <e:Sum>
       <e:Sum>
           <e:Const>
               8
           </e:Const>
           <e:Const>
               4
           </e:Const>
       </e:Sum>
        <e:Sum>
            <e:Const>
                1
            </e:Const>
            <e:Const>
                2
            </e:Const>
        </e:Sum>
    </e:Sum>
</e:EE>

问题出现在XSLT 上这是我迄今为止尝试过的:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:e="expr"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output
        method="xml"
        indent="yes"
        encoding="iso-8859-1"/>

    <xsl:template match="e:EE">
        <xsl:copy>
            <xsl:apply-templates select="e:Sum" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="e:Sum">
        <xsl:variable name="v1">
            <xsl:apply-templates select="e:Const[1]"></xsl:apply-templates>
        </xsl:variable>
        <xsl:variable name="v2">
            <xsl:apply-templates select="e:Const[2]"></xsl:apply-templates>
        </xsl:variable>
        <Operation>
            <xsl:value-of select="$v1" />
            +
            <xsl:value-of select="$v2" />
        </Operation>
        <result>
        <xsl:value-of select="$v1 + $v2"/>
        </result>
    </xsl:template>

</xsl:stylesheet>

这在我sum只有 2 时有效Const即总和(8,4)

但是,我想递归地将 应用于Sum templateXML 中的每个表达式。

金利来

您可以通过有效地使用模板来做到这一点 - 定义模板以便他们知道如何处理手头的操作。

在 Sum 的情况下,这将是:

  1. 获取第一个操作数(第一个子元素)的结果值
  2. 获取第二个操作数(第二个子元素)的结果值
  3. 将它们加在一起。

Sum 不需要知道它有什么样的操作数。它可以只对它们应用模板并让 XSLT 解决这个问题。这是我们得到的:

<xsl:template match="e:Sum">
  <xsl:variable name="v1">
    <xsl:apply-templates select="*[1]" />
  </xsl:variable>
  <xsl:variable name="v2">
    <xsl:apply-templates select="*[2]" />
  </xsl:variable>

  <xsl:value-of select="$v1 + $v2"/>
</xsl:template>

为 定义一个模板可能是有意义的e:Const,所以它被明确定义:

<xsl:template match="e:Const">
  <xsl:value-of select ="."/>
</xsl:template>

这是一个完整的 XSLT,添加了e:Multiply一个一元运算 ( e:Invert):

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

  <xsl:output
      method="xml"
      indent="yes"
      encoding="iso-8859-1"/>

  <xsl:template match="e:EE">
    <xsl:copy>
      <xsl:apply-templates select="*[1]" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="e:Sum">
    <xsl:variable name="v1">
      <xsl:apply-templates select="*[1]" />
    </xsl:variable>
    <xsl:variable name="v2">
      <xsl:apply-templates select="*[2]" />
    </xsl:variable>

    <xsl:value-of select="$v1 + $v2"/>
  </xsl:template>

  <xsl:template match="e:Multiply">
    <xsl:variable name="v1">
      <xsl:apply-templates select="*[1]" />
    </xsl:variable>
    <xsl:variable name="v2">
      <xsl:apply-templates select="*[2]" />
    </xsl:variable>

    <xsl:value-of select="$v1 * $v2"/>
  </xsl:template>

  <xsl:template match="e:Invert">
  <xsl:variable name="v1">
      <xsl:apply-templates select="*[1]" />
  </xsl:variable>

    <xsl:value-of select="1 div $v1"/>
  </xsl:template>

  <xsl:template match="e:Const">
    <xsl:value-of select ="."/>
  </xsl:template>

</xsl:stylesheet>

在此输入 XML 上运行时:

<?xml version="1.0" encoding="UTF-8"?>
<e:EE xmlns:e="expr"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="xxx/xxx/xxx...">
  <e:Sum>
    <e:Sum>
      <e:Const>8</e:Const>
      <e:Const>4</e:Const>
    </e:Sum>
    <e:Sum>
      <e:Multiply>
        <e:Invert>
          <e:Const>3</e:Const>
        </e:Invert>
        <e:Const>6</e:Const>
      </e:Multiply>
      <e:Const>2</e:Const>
    </e:Sum>
  </e:Sum>
</e:EE>

结果是:

<e:EE xmlns:e="expr" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">16</e:EE>

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何用 xslt 转换这个 xml?

使用一个XSLT生成XML和XSD文档

如何使用 xslt 和 xml 显示图像?

如何从XML和XSLT获取HTML文件

XSLT对XML和CSV一样?

用C++做一个简单的计算器时如何选择运算符?

如何用XSLT替换XML中的部分行?

如何使用XSLT和javascript从XML创建HTML?

Xslt:如何使用条件解析和回显xml数据

如何使用JSP / HTML和XSLT创建XML文件

<product to xml 标签后如何获取和转换属性| XSLT

如何使用XSLT替换XML中的前缀和命名空间

XSLT - 比较和组合两个 XML 文件

解释在一个参数和操作数(除法或乘法)的情况下RPN计算器应如何工作

如何用“和”替换最后一个逗号

如何用angular和php计算?

如何使用 XSLT 和 Python 将 xml 的子子元素移动到新的 xml 文件?

XSLT:如何用所有同级的串联代替第一个同级?

如何使用XSLT 2.0在XML文档中查找第一个表

如何使用XSLT根据另一个节点的内容获取XML节点的值?

如何使用XSLT将XML元素的第一个属性的值重命名?

如何使用 XSLT 从另一个 XML 文档提供属性值?

XSLT:从输入 XML 创建具有唯一和排序日期的新 XML 节点

如何使用XSLT中第二个xml输入中的变量修改一个xml输入?

使用XSLT换行符和第一个值开头的空格将XML转换为CSV

XSLT和XML内容未在Microsft Edge和Internet Explorer浏览器中加载

如何使用XSLT 1计算XML元素中的值

Xslt/XML:如何从输入值动态计算分割点

循环使用XML和XSLT连接字段