我正在使用XSD、XML和XSLT构建表达式计算器。
目前只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 template
XML 中的每个表达式。
您可以通过有效地使用模板来做到这一点 - 定义模板以便他们知道如何处理手头的操作。
在 Sum 的情况下,这将是:
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] 删除。
我来说两句