以下是我的代码的缩写示例。
我想计算组(或gid)中每个条目的平均 target_value 在一个简单的伪代码中,这将按以下方式编写:
total target_value of entries with gid "001" / amount of entries with gid "001"
但是,由于XML对我来说相当新,我想知道如何重用已经计算过的值(参见下面的XSL)进行进一步的计算? 变量是最有效的方法,如果是,它们应该在何处/如何定义?
XML:
<root>
<entry gid ="001">
<level_1>
<target_value>50</target_value>
</level_1>
</entry>
<entry gid ="001">
<level_1>
<target_value>30</target_value>
</level_1>
</entry>
</root>
XSL:
<xsl:value-of select="sum(entry[@gid='001']/level_1/target_value)" />
结果: 80
任何帮助都会受到很大关注!
答案 0 :(得分:0)
<xsl:value-of select="
sum(entry[@gid='001']/level_1/target_value) div count(entry[@gid='001'])
" />
当然,您可以将计算值保存在变量中以供重复使用:
<xsl:variable
name="target_value_sum"
select="sum(entry[@gid='001']/level_1/target_value)"
/>
<xsl:value-of select="$target_value_sum div count(entry[@gid='001'])" />
在这种情况下没有必要。
答案 1 :(得分:0)
这个xslt 1.0样式表...
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="entry-by-gid" match="entry" use="@gid" />
<xsl:template match="root">
<entries>
<xsl:apply-templates select="entry
[generate-id(.) = generate-id( key('entry-by-gid',@gid)[1])]"/>
</entries>
</xsl:template>
<xsl:template match="entry">
<entry-average gid="{@gid}">
<xsl:value-of select="sum(../entry[@gid=current()/@gid]/level_1/target_value) div
count(../entry[@gid=current()/@gid]/level_1/target_value)"/>
</entry-average>
</xsl:template>
</xsl:stylesheet>
将产生类似..
的输出<?xml version="1.0" encoding="utf-8"?>
<entries>
<entry-average gid="001">40</entry-average>
</entries>
对于xslt 2.0,请使用for-each-group。这是一个XSLT 2.0样式表来做同样的事情。
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<entries>
<xsl:for-each-group select="*/entry" group-by="@gid">
<entry-average gid="{@gid}">
<xsl:value-of select="sum(../entry[@gid=current-grouping-key()]/level_1/target_value) div
count(../entry[@gid=current-grouping-key()]/level_1/target_value)"/>
</entry-average>
</xsl:for-each-group>
</entries>
</xsl:template>
</xsl:stylesheet>
答案 2 :(得分:0)
我会把它写成两个文件范围的变量,第一个将节点集选为变量,第二个计算平均值。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text" />
<xsl:variable name="target_values" select="/root/entry[@gid='001']/level_1/target_value" />
<xsl:variable name="mean_target_values" select="sum($target_values) div count($target_values)" />
<xsl:template match="/root">
<xsl:value-of select="format-number($mean_target_values, '0.00')" />
</xsl:template>
</xsl:stylesheet>
由于您提到格式化浮点数我已将其修改为使用format-number
函数。格式符号与Java DecimalForamt类相同,文档为here。我使用了0.00
,它给出了两位小数。我认为如果你需要的话,如何更改它很清楚。
答案 3 :(得分:0)
看过你的评论,你想为所有具有相同@gid
的条目组提供此信息,我必须编写一个与我之前的解决方案截然不同的解决方案,它应得到新的答案。
不幸的是,以这种方式进行分组并不是最简单的XSL,但现在就是这样。请注意,使用所谓的Muenchian方法可以提高效率,但我已经用这种方式编写了(相对)简单性和可读性。 (我发现Sean B. Durkin使用了更快的方法,因此您可以对它们进行比较。)
它的工作方式是xsl:for-each
遍历所有<entry>
元素,这些元素的gid
属性与之前的所有<entry>
元素不同。这将选择gid
属性的所有唯一值,这些值将复制到$gid
变量。
之后,具有相同<target_value>
属性的<entry>
元素中的所有gid
元素都将收集到节点集中并分配给变量$target_values
。在那之后,很容易计算它们并找到它们的总数,将它们除以另一个来得到均值,并将其分配给另一个变量。
然后只输出gid
属性值和每个不同gid
的均值。 $nl
变量是一个便利变量,等于用于布局输出的换行符。
我希望从这里推断出你需要的最终解决方案很容易。如果你遇到困难,请再问一次。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text" />
<xsl:variable name="nl">
<xsl:text>
</xsl:text>
</xsl:variable>
<xsl:template match="/root">
<xsl:for-each select="entry[not(@gid = preceding-sibling::entry/@gid)]">
<xsl:sort select="@gid" />
<xsl:variable name="gid" select="@gid" />
<xsl:variable name="target_values" select="/root/entry[@gid=$gid]/level_1/target_value" />
<xsl:variable name="mean_target_values" select="sum($target_values) div count($target_values)" />
<xsl:value-of select="concat('GID: ', $gid, $nl)" />
<xsl:value-of select="concat('mean target value ', format-number($mean_target_values, '0.00'), $nl)" />
<xsl:value-of select="$nl" />
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
产生此输出
GID: 001
mean target value 40.00
GID: 002
mean target value 60.33
GID: 003
mean target value 27.00
应用于此XML
<?xml version="1.0" encoding="UTF-8"?>
<root>
<entry gid ="001">
<level_1>
<target_value>50</target_value>
</level_1>
</entry>
<entry gid ="001">
<level_1>
<target_value>30</target_value>
</level_1>
</entry>
<entry gid ="002">
<level_1>
<target_value>40</target_value>
</level_1>
</entry>
<entry gid ="002">
<level_1>
<target_value>72</target_value>
</level_1>
</entry>
<entry gid ="002">
<level_1>
<target_value>69</target_value>
</level_1>
</entry>
<entry gid ="003">
<level_1>
<target_value>14</target_value>
</level_1>
</entry>
<entry gid ="003">
<level_1>
<target_value>44</target_value>
</level_1>
</entry>
<entry gid ="003">
<level_1>
<target_value>23</target_value>
</level_1>
</entry>
</root>