我有一个相当复杂的XML文件,我需要使用XSL对其中的一些值进行加权平均。我能够完成值的权重OR的总和,但我无法使乘法工作。我收到一个错误:
XPTY0004:第一个不允许包含多个项目的序列 ' *'
的操作数
我无法共享XML,但我已将XML简化为以下示例(假设有大量的foos):
<group>
<fooList>
<foo>
<attributeList>
<Attribute ID="1" Weight="0.5">
<otherParams />
</Attribute>
</attributeList>
<Properties>
<PhysicalProperties>
<Volume Average="125" Unknown="50" />
</PhysicalProperties>
</Properties>
</foo>
</fooList>
</group>
我目前获得加权平均值的尝试如下:
<xsl:variable name="WeightedVolume" select="sum(/group/fooList/foo[attributeList/Attribute/[@ID=$test_id]]/attributeList/Attribute/@Weight * /group/fooList/foo[attributeList/Attribute/[@ID=$test_id]]/Properties/PhysicalProperties/Volume/@Average)"/>
我知道有类似的问题可用 - 但大多数问题都涉及到汇总和乘法foo等问题
<foo>
<Weight>0.5</Weight>
<VolumeAverage>125</VolumeAverage>
</foo>
这个StackOverflow Question的答案对我有吸引力,但我似乎无法使其发挥作用。
我使用Saxonica的Saxon-HE 9.5.1.1N,使用Visual Studio 2013.
被修改 我能够为XSL 2获得一些工作,但需要为XSL1提供支持。
<xsl:variable name="WeightedVolume" select="sum(for $i in /group/FooList/foo[attributeList/Attribute[@ID=$test_id] return $i/AttributeList/Attribute/@Weight * $i/Properties/PhysicalProperties/Volume/@Average)"/>
答案 0 :(得分:2)
要按照您链接到的问题中的示例,您将在XSLT 2.0 / XPath 2.0中使用它:
<xsl:variable name="FoosToCalculate"
select="/group/fooList/foo[attributeList/Attribute/@ID = $test_id]" />
<xsl:variable name="WeightedVolume"
select="sum($FoosToCalculate/(attributeList/Attribute/@Weight *
Properties/PhysicalProperties/Volume/@Average)
)"/>
在XSLT 1.0中进行此求和涉及更多,并且通常涉及使用递归模板或node-set()
函数的某些表现形式。以下是后者的一个例子:
<xsl:stylesheet version="1.0"
xmlns:ex="http://exslt.org/common"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<!-- determine $test_id however you need to -->
<xsl:variable name="products">
<xsl:for-each
select="/group/fooList/foo[attributeList/Attribute/@ID = $test_id]">
<product>
<xsl:value-of select="attributeList/Attribute/@Weight *
Properties/PhysicalProperties/Volume/@Average" />
</product>
</xsl:for-each>
</xsl:variable>
<xsl:value-of select="sum(ex:node-set($products)/product)"/>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:1)
为了完整性,如果要在XSLT 1.0中对计算数量求和,有三种方法:
(a)递归:编写一个递归模板,逐个处理序列中的项目,计算总数。
(b)创建一个XML树,其中计算的数量是节点值,然后使用sum()函数处理此树。要在单个样式表中执行此操作,您将需要exslt:node-set()扩展函数。
(c)使用XSLT供应商提供的扩展功能,或使用供应商提供的设施进行用户编写以调用外部功能。
在XSLT 2.0中,始终可以使用构造
来完成sum(for $x in node-set return f($x))
其中f是计算数量的函数。