English 中文(简体)
XSL: 在进一步的计算中使用计算值
原标题:XSL: Using Calculated values in further calculations
  • 时间:2012-05-22 14:39:39
  •  标签:
  • xml
  • xslt

以下是我代码的缩略例子。

I want to calculate the average target_value of each entry in a group (or gid) In a simple pseudocode this would be written in the following way:

total target_value of entries with gid "001" / amount of entries with gid "001"

However, since XML is fairly new to me, I wish to know how to reuse the values already calculated (see the XSL below) for further calculations? Is variables the most effective way to go, and if so, where/how should they be defined?

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)" />

Result: 80

任何帮助都会大受欢迎!

最佳回答
<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 ])" />

本案中没有必要这样做。

问题回答

我会写成两个文件范围的变量, 第一个选择节点变成一个变量, 第二个计算平均值。

<?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 Decimal Foramt 类相同,文档为http://docs.oracle.com/javase/1.4.2/docs/api/java/text/DecimalFormat.html>rel=“nofolpol”>这里。我曾经使用过 0.00 ,它给了两个小数位数位置。我想如果需要,可以清楚修改它。

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, 用于每个组。 这里有一个 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>

看到您的评论, 即您想要为所有组的条目提供相同 的这种信息, 我必须写出一个与我先前的解答截然不同的解答, 以至于值得给予新的解答 。

不幸的是,这样分组并不是XSL中最简单的一小块,而是这里。请注意,使用所谓的Muenchian方法可以提高效率,但我写了这个方法是为了(相对的)简单易读。 (我看到<?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>




相关问题
how to represent it in dtd?

I have two element action and guid. guid is a required field when action is add. but when action is del it will not appear in file. How to represent this in dtd ?

.Net application configuration add xml-data

I need to add xml-content to my application configuration file. Is there a way to add it directly to the appSettings section or do I need to implement a configSection? Is it possible to add the xml ...

XStream serializing collections

I have a class structure that I would like to serialize with Xstream. The root class contains a collection of other objects (of varying types). I would like to only serialize part of the objects that ...

MS Word splits words in its XML format

I have a Word 2003 document saved as a XML in WordProcessingML format. It contains few placeholders which will be dynamically replaced by an appropriate content. But, the problem is that Word ...

Merging an XML file with a list of changes

I have two XML files that are generated by another application I have no control over. The first is a settings file, and the second is a list of changes that should be applied to the first. Main ...

How do I check if a node has no siblings?

I have a org.w3c.dom.Node object. I would like to see if it has any other siblings. Here s what I have tried: Node sibling = node.getNextSibling(); if(sibling == null) return true; else ...

Ordering a hash to xml: Rails

I m building an xml document from a hash. The xml attributes need to be in order. How can this be accomplished? hash.to_xml

热门标签