XSLT 1.0 - 基于来自2个节点的条件的Sum列

时间:2014-04-07 17:56:07

标签: xml xslt sharepoint-2007 dataviewwebpart

我有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的年份=今年,或者如果CheckDate的年份=今年,我需要将Cost列相加。

在上面的方案中,请求ID 2-5符合标准。总数应该是8100.我已经尝试了几种方法来获得总和,但没有一种方法可行。任何帮助表示赞赏。

3 个答案:

答案 0 :(得分:0)

您可以使用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>

答案 1 :(得分:0)

这将输出<sum>5600</sum>

<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>

答案 2 :(得分:0)

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

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

<?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>