【问题标题】:XSLT 1.0 - Sum column based on conditions from 2 nodesXSLT 1.0 - 基于来自 2 个节点的条件的总和列
【发布时间】:2014-04-07 17:56:07
【问题描述】:

我有 2 个数据源(请求和实际)。以下是我的 xml 示例:

<dsQuery Response>
  <Request>
    <Rows>
      <Row>
        <TravelDate>2013-10-05T05:00:00Z</TravelDate>
        <ID>1</ID>
       <Cost>1000</Cost>
     </Row>
     <Row>
        <TravelDate>2013-12-31T05:00:00Z</TravelDate>
        <ID>2</ID
        <Cost>2500</Cost>
     </Row>
     <Row>
      <TravelDate>2014-01-13T06:00:00Z</TravelDate>
      <ID>3</ID>
      <Cost>1300</Cost>
     </Row>
   <Row>
      <TravelDate>2014-02-01T06:00:00Z</TravelDate>
      <ID>4</ID>
      <Cost>2300</Cost>
    </Row>
    <Row>
      <TravelDate>2014-08-01T06:00:00Z</TravelDate>
      <ID>5</ID>
      <Cost>2000</Cost>
    </Row>
    </Rows>
  </Request>
  <Actual>
    <Rows>
      <Row>
        <ID>10</ID>
        <FormID>2</FormID>
        <CheckDate>2014-01-01T12:00:00Z</CheckDate>
      </Row>
      <Row>
        <ID>11</ID>
        <FormID>3</FormID>
        <CheckDate>2014-01-31T12:00:00Z</CheckDate>
    </Row>
    <Row>
      <ID>12</ID>
      <FormID>4</FormID>
      <CheckDate>2014-02-15T12:00:00Z</CheckDate>
    </Row>
  </Rows>
</Actual>
</dsQuery Response>

如果 TravelDate 的年份 = This year 或者 CheckDate 的年份 = This Year,我需要对 Cost 列求和。

在上述场景中,请求 ID 2-5 符合条件。总数应该是 8100。我尝试了几种方法来获得总和,但没有一个有效。任何帮助表示赞赏。

【问题讨论】:

  • &lt;Row&gt;&lt;ID&gt;2&lt;/ID&gt;&lt;/Row&gt; 有 '2013-12-31T05:00:00Z`,这不是今年。
  • 请修正您的输入 XML 示例:&lt;dsQuery Response&gt; 不是有效的元素名称,并且您在第 11 行有一个打开的标签。

标签: xml xslt sharepoint-2007 dataviewwebpart


【解决方案1】:

您可以使用xsl:variable 来保存过滤后的Row 元素并将它们相加:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml"/>
    <xsl:template match="/dsQueryResponse">

        <xsl:variable name="ThisYear" select="2014" />
        <xsl:variable name="Rows">
            <xsl:for-each select="//Cost">
                <xsl:variable name="ID" select="../ID" />
                <xsl:if test="
                    starts-with(../TravelDate, $ThisYear) or
                    (
                        /*/Actual/*/*[FormID = $ID and 
                        starts-with(CheckDate, $ThisYear) ]
                    )">
                    <xsl:copy-of select=".." />
                </xsl:if>
            </xsl:for-each>
        </xsl:variable>

        <xsl:value-of select="sum($Rows//Cost)" />

    </xsl:template>
</xsl:stylesheet>

【讨论】:

  • 您不能在 XSLT 1.0 中对结果树片段求和。
【解决方案2】:

这将输出&lt;sum&gt;5600&lt;/sum&gt;

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
   <xsl:param name="year" select="string('2014')"/>

   <xsl:template match="/"> 
       <sum>
         <xsl:value-of select="sum(//Request/Rows/Row[substring-before(TravelDate/text(),'-')=$year]/Cost)  
                     + sum(//Actual/Rows/Row[substring-before(CheckDate,'-')=$year]/Cost)"/>
       </sum>

   </xsl:template>
</xsl:stylesheet>

【讨论】:

  • Actual 行不包含 Cost 元素
  • @RubensFarias 在示例 xml 中为 true,但我读到此 I need to sum the Cost column if the year for TravelDate=This year OR if the year of the CheckDate = This Year. 表示可能有一个 Cost 列与 CheckDate 相邻。
【解决方案3】:

您要求的是 XSLT 1.0 解决方案,但 XSLT 1.0 中没有“今年”;您将需要使用 EXSLT 扩展函数或在运行时将当前日期/年份作为参数传递。

除此之外。我建议您使用 key 从“相关”实际检查日期获取数据:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:date="http://exslt.org/dates-and-times"
extension-element-prefixes="date">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:param name="thisYear" select="substring(date:date-time(), 1, 4)" />

<xsl:key name="check" match="CheckDate" use="../FormID" />

<xsl:template match="/">
    <sum>
        <xsl:value-of select="sum(dsQueryResponse/Request/Rows/Row[substring(TravelDate, 1, 4)=$thisYear or substring(key('check',ID) , 1, 4)=$thisYear]/Cost)"/>
    </sum>  
</xsl:template>

</xsl:stylesheet>

当应用于更正的示例输入时:

<dsQueryResponse>
  <Request>
    <Rows>
      <Row>
        <TravelDate>2013-10-05T05:00:00Z</TravelDate>
        <ID>1</ID>
       <Cost>1000</Cost>
     </Row>
     <Row>
        <TravelDate>2013-12-31T05:00:00Z</TravelDate>
        <ID>2</ID>
        <Cost>2500</Cost>
     </Row>
     <Row>
      <TravelDate>2014-01-13T06:00:00Z</TravelDate>
      <ID>3</ID>
      <Cost>1300</Cost>
     </Row>
   <Row>
      <TravelDate>2014-02-01T06:00:00Z</TravelDate>
      <ID>4</ID>
      <Cost>2300</Cost>
    </Row>
    <Row>
      <TravelDate>2014-08-01T06:00:00Z</TravelDate>
      <ID>5</ID>
      <Cost>2000</Cost>
    </Row>
    </Rows>
  </Request>
  <Actual>
    <Rows>
      <Row>
        <ID>10</ID>
        <FormID>2</FormID>
        <CheckDate>2014-01-01T12:00:00Z</CheckDate>
      </Row>
      <Row>
        <ID>11</ID>
        <FormID>3</FormID>
        <CheckDate>2014-01-31T12:00:00Z</CheckDate>
    </Row>
    <Row>
      <ID>12</ID>
      <FormID>4</FormID>
      <CheckDate>2014-02-15T12:00:00Z</CheckDate>
    </Row>
  </Rows>
</Actual>
</dsQueryResponse>

结果是:

<?xml version="1.0" encoding="UTF-8"?>
<sum>8100</sum>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-18
    • 2018-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-27
    相关资源
    最近更新 更多