【问题标题】:XSLT running total for non-siblings非兄弟姐妹的 XSLT 运行总计
【发布时间】:2018-02-07 18:42:33
【问题描述】:

我正在尝试计算 XML 文档中的成本和页面元素的总和,如下所示。

鉴于成本和页面都是 OrderAmounts 的子项,我不知道如何完成运行总计。我搜索了其他答案,但只能找到计算兄弟元素运行总数的参考。

XML

<Root>
  <Info>
    <CustomerName>Clay Allen</CustomerName>
    <CustAddr>123 Main St</CustAddr>
    <Date>2018-02-07</Date>
  </Info>
  <Details>
    <AdditionalDetails>
      <OrderDetails>
        <Order>
         <OrderNumber>A1</OrderNumber>
         <OrderAmounts>
           <Cost>100</Cost>
           <Pages>1325</Pages>
         </OrderAmounts>
        </Order>
        <Order>
         <OrderNumber>A2</OrderNumber>
         <OrderAmounts>
           <Cost>75</Cost>
           <Pages>950</Pages>
         </OrderAmounts>
        </Order>
      </OrderDetails>
    </AdditionalDetails>
  </Details>
</Root>

我的 XSL

<xsl:for-each select="Root/Details/AdditionalDetails/OrderDetails/Order">
  (Cumulative value: <xsl:variable name="temp1" select="sum(preceding-sibling::Order)+OrderAmounts/Cost"/><xsl:value-of select="$temp1"/>)<br/>
  (Cumulative value: <xsl:variable name="temp2" select="sum(preceding-sibling::Order)+OrderAmounts/Pages"/><xsl:value-of select="$temp2"/>)
  <br/><br/>
</xsl:for-each>

产生输出

100
1325

75
950

期望的输出

175
2275

建议。

【问题讨论】:

  • 请(总是!)说出您使用的 XSLT 版本。这样的问题在 2.0 或 3.0 中比在 1.0 中要容易得多,但没有人愿意发现他们浪费时间为错误的版本提供解决方案。
  • 谢谢。为了将来参考,这个问题与 XSLT 3.0 有关。

标签: xml xslt


【解决方案1】:

'sum()' 函数需要任何节点集来评估总数(它们不需要是兄弟姐妹),因此您的问题是找到正确的 XPATH 来为 sum 函数选择节点。所以以下应该可以工作。

<TotalCosts>
    <xsl:value-of select="sum(//OrderAmounts/Cost)"/>
</TotalCosts>
<TotalPages>
    <xsl:value-of select="sum(//OrderAmounts/Pages)"/>
</TotalPages>

【讨论】:

  • 非常感谢!我忘了提及为什么我使用的是累计。如果页数>1000,我们需要将成本添加到总成本中。因此,我们需要在每个循环中添加一个条件来检查页面的值,然后在适用的情况下将成本添加到变量中。这可能是因为 $temp 在循环之后超出范围吗?
  • 您可以在循环之前将总和存储在一个变量中,如果条件适用,可以在循环内使用它。
【解决方案2】:

简单的答案是你想要sum(preceding-sibling::OrderOrderAmounts/Cost)+OrderAmounts/Cost而不是sum(preceding-sibling::Order)+OrderAmounts/Cost

但是,订单数量是二次方的,对于 XSLT 3.0,您可以使用 xsl:iterate 来改进这一点以计算运行总数:

<xsl:iterate select="Order">
  <xsl:param name="cost-so-far" as="xs:decimal" select="0"/>
  <xsl:param name="pages-so-far" as="xs:integer" select="0"/>
  ...
  <xsl:next-iteration>
    <xsl:with-param name="cost-so-far" select="$cost-so-far + xs:decimal(OrderAmounts/Cost)"/> 
    <xsl:with-param name="pages-so-far" select="$pages-so-far + xs:decimal(OrderAmounts/Pages)"/> 
  </xsl:next-iteration>
</xsl:iterate>

【讨论】:

    猜你喜欢
    • 2023-03-22
    • 1970-01-01
    • 2019-05-06
    • 2015-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-12
    • 1970-01-01
    相关资源
    最近更新 更多