【问题标题】:Calculate average with xslt用 xslt 计算平均值
【发布时间】:2015-05-22 18:23:18
【问题描述】:

我正在尝试使用 xslt 打印平均值,并且很难找到一种方法。 我在单独的节点中有答案,在单独的节点中有问题。需要将问题ID与答案匹配并计算平均值

<?xml version="1.0" encoding="ISO-8859-1"?>
 <?xml-stylesheet type="text/xsl" href="test.xsl"?>
   <details>
     <detail>
      <answersall>
        <answers>
          <question id="1"/>
          <answer>4</answer>
          <note>test</note>
      </answers>
      <answers>
        <question id="2"/>
        <answer>2</answer>
      </answers>
      <answers>
        <question id="3"/>
        <answer>2</answer>
      </answers>
      <answers>
        <question id="4"/>
        <answer>3</answer>
      </answers>
    </answerall>
  </detail>
  <questions>
   <question id="1" text="Hello how are you" section="a"/>
   <question id="2" text="how was your day" section="a"/>
   <question id="3" text="it was good" section="b"/>
   <question id="4" text="take care" section="b"/>
  </questions>
</details>

我正在尝试打印这样的内容
Question Answer
Section A 3 (average)
1. Hello how are you 4
2.How was your day 2
Section B 2.5
3. It was good 2
4. Take Care 3

我有打印问题和答案的部分,但没有打印平均值。我知道我不能在 for 循环中使用变量。

下面是我的 xslt。

<?xml version="1.0" ?>
 <xsl:stylesheet version="1.0"    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
   <html>
     <body>
      <h2><center>Details</center></h2>
       <table>
         <tr>
           <td>Section A</td>
           <td>????</td>
         </tr>
         <xsl:for-each select="details/questions/question[@section='a']">
           <xsl:variable name="id" select="@id"/>
             <tr>
                <td><xsl:value-of select="@text"/></td>
                <td><xsl:value-of select="//answers[question/@id=$id]/answer"/></td>
             </tr>
         </xsl:for-each>
     </table>
  </body>
</html>

【问题讨论】:

  • 基本上,这是一个分组问题。请参阅jenitennison.com/xslt/grouping/muenchian.html 和 SO 上的许多示例。 -- 另请注意:您的 XML 格式不正确,并且您向我们展示的 XSLT 使用了未定义的变量。
  • 我看这个例子。 stackoverflow.com/questions/16222647/…。但我无法弄清楚如何根据该部分指出选择问题并在单独的节点中找到平均值
  • 是否总是有两个部分,a 和 b?
  • 实际上有 5 个。为简单起见,我添加了 2 个。
  • 是的,但它们是常量吗? IOW,可以将它们硬编码到样式表中吗?

标签: xml xslt


【解决方案1】:

以下是您可以作为起点的内容:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="question-by-section" match="question" use="@section" />
<xsl:key name="answer-by-question" match="answers" use="question/@id" />

<xsl:template match="/">
    <table border="1">
        <tr>
            <th>Question</th>
            <th>Answer</th>
        </tr>
        <xsl:call-template name="generate-section">     
            <xsl:with-param name="section">a</xsl:with-param>
        </xsl:call-template>
        <xsl:call-template name="generate-section">     
            <xsl:with-param name="section">b</xsl:with-param>
        </xsl:call-template>
     </table>
</xsl:template>

<xsl:template name="generate-section">
    <xsl:param name="section"/>
    <xsl:variable name="questions" select="key('question-by-section', $section)" />
    <xsl:variable name="answers" select="key('answer-by-question', $questions/@id)" />
    <tr>
        <th>
            <xsl:value-of select="concat('Section ', $section)" />
        </th>
        <th>
            <xsl:value-of select="sum($answers/answer) div count($answers)" />          
        </th>
    </tr>
    <xsl:for-each select="$questions">
        <tr>
            <td><xsl:value-of select="@text"/></td>
            <td><xsl:value-of select="key('answer-by-question', @id)/answer"/></td>
        </tr>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

应用于您的输入(在更正 answersall 与 answerall 不匹配之后!),结果将如下所示:

我强烈建议您采用Muenchian grouping 来选择不同的部分,而不是硬编码重复调用此处显示的命名模板。

【讨论】:

  • @Daniel Haley 欢迎您从这里复制平均机制。
  • 我很感激,但我会删除我的答案。 +1 以获得很好的答案(像往常一样)。
  • 这行得通。我肯定会更改部分的硬编码值并放入 for 循环以从 xml 读取。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-14
  • 2012-06-19
  • 1970-01-01
相关资源
最近更新 更多