【问题标题】:XSLT Transformation. Multiply and then sumXSLT 转换。相乘然后相加
【发布时间】:2013-02-02 14:05:51
【问题描述】:

我需要通过添加订单价格总和将我的 XML 从一种格式转换为另一种格式。计算为Sum total (itemPrice*itemQty)。我的请求 XML 如下

 <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
       <soap:Body>
          <ns2:fetchOrderListResponse xmlns:ns2="http://impl.lob.xyz.com/">
             <return>
                <customerOrderNumber>1</customerOrderNumber>
                <orderDetails>
                   <itemPrice>2.0</itemPrice>
  <itemQty>1</itemQty>
                   <orderDetailsId>37516016-D71B-4790-951F-55D00B0CC159</orderDetailsId>
                </orderDetails>
                <orderDetails>
                   <itemPrice>5.0</itemPrice>
                   <itemQty>3</itemQty>
                   <itemUnit>0</itemUnit>
                </orderDetails>
                <orderId>84EC371D-40CA-455E-A0FA-7EA733E9BFD3</orderId>
             </return>
             <return>
                <customerOrderNumber>1</customerOrderNumber>
                <deliverydate>2013-02-06T00:00:00+05:30</deliverydate>
                <orderDetails>
                   <itemPrice>7.0</itemPrice>
                   <itemQty>1</itemQty>
                   <orderDetailsId>9A5030BE-F95F-4C62-B5A2-41FF85423218</orderDetailsId>
                </orderDetails>
                <orderDetails>
                   <itemPrice>9.0</itemPrice>
                   <itemQty>5</itemQty>
                   <orderDetailsId>65A8B3BE-D407-43D8-8754-EA1E26AA56E4</orderDetailsId>
                </orderDetails>
                <orderId>0BDCB222-0117-47A9-8813-DF03A1D19E5E</orderId>
             </return>
          </ns2:fetchOrderListResponse>
       </soap:Body>
    </soap:Envelope>

我需要在计算广告添加后将其转换为以下格式吗?使用 XSLT 的元素。转换后的 XML 应如下所示。请在这里提供帮助。

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
      <ns2:fetchOrderListResponse xmlns:ns2="http://impl.lob.xyz.com/">
         <return>
            <customerOrderNumber>1</customerOrderNumber>
            <orderDetails>
               <itemPrice>2.0</itemPrice>
               <itemQty>1</itemQty>
               <orderDetailsId>37516016-D71B-4790-951F-55D00B0CC159</orderDetailsId>
            </orderDetails>
            <orderDetails>
               <itemPrice>5.0</itemPrice>
               <itemQty>3</itemQty>
            </orderDetails>
            <orderId>84EC371D-40CA-455E-A0FA-7EA733E9BFD3</orderId>
            **<ordertotal>17.0</ordertotal>**
         </return>
         <return>
            <customerOrderNumber>1</customerOrderNumber>
            <deliverydate>2013-02-06T00:00:00+05:30</deliverydate>
            <orderDetails>
               <itemPrice>7.0</itemPrice>
               <itemQty>1</itemQty>
               <orderDetailsId>9A5030BE-F95F-4C62-B5A2-41FF85423218</orderDetailsId>
            </orderDetails>
            <orderDetails>
               <itemPrice>9.0</itemPrice>
               <itemQty>5</itemQty>
               <orderDetailsId>65A8B3BE-D407-43D8-8754-EA1E26AA56E4</orderDetailsId>
            </orderDetails>
            <orderId>0BDCB222-0117-47A9-8813-DF03A1D19E5E</orderId>
            **<ordertotal>52.0</ordertotal>**
         </return>
      </ns2:fetchOrderListResponse>
   </soap:Body>
</soap:Envelope>

【问题讨论】:

标签: xslt xslt-1.0 xslt-2.0


【解决方案1】:

XSLT 2.0 解决方案是:

<xsl:stylesheet version="2.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" indent="yes" />

    <!-- Identity template : elements and attributes are copied by default -->
    <xsl:template match="*|@*">
        <xsl:copy>
            <xsl:apply-templates select="*|@*" />
        </xsl:copy>
    </xsl:template>

    <!-- When matching return we add the order total as its last child -->
    <xsl:template match="return">
        <xsl:copy>
            <xsl:copy-of select="@*|*" />
            <ordertotal>
                <xsl:value-of select="sum(orderDetails/(itemPrice*itemQty))" />
            </ordertotal>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

如果您使用的是 XSLT 1.0(没有扩展功能),您必须使用递归来实现您想要的:

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" indent="yes" />

    <xsl:template match="*|@*">
        <xsl:copy>
            <xsl:apply-templates select="*|@*" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="return">
        <xsl:copy>
            <xsl:copy-of select="@*|*" />
            <ordertotal><xsl:call-template name="calculate-total" /></ordertotal>
        </xsl:copy>
    </xsl:template>

    <!-- Recursive template -->
    <xsl:template name="calculate-total">
        <!-- Select by default the set of orderDetails from the current context -->
        <xsl:param name="orderDetails"
                   select="orderDetails" />
        <!-- Param which is going to keep track of the result step by step -->
        <xsl:param name="total"
                   select="'0'" />

        <xsl:choose>
            <!-- If we have remaining order details, recurse -->
            <xsl:when test="$orderDetails">
                <xsl:call-template name="calculate-total">
                    <!-- Remove the current element for the next step -->
                    <xsl:with-param name="orderDetails"
                                    select="$orderDetails[position() > 1]" />
                    <!-- Do the partial operation for the current element, and continue to the next step -->
                    <xsl:with-param name="total"
                                    select="$total + ($orderDetails[1]/itemPrice * $orderDetails[1]/itemQty)" />
                </xsl:call-template>        
            </xsl:when>
            <!-- Output the result -->
            <xsl:otherwise>
                <xsl:value-of select="$total" />
            </xsl:otherwise>
        </xsl:choose>

    </xsl:template>

</xsl:stylesheet>

【讨论】:

    【解决方案2】:

    您已标记问题 XSLT2.0,这意味着求和很简单。假设您位于 return 元素上,您只需执行此操作即可获取 ordertotal

    <ordertotal>
       <xsl:value-of select="sum(orderDetails/(itemPrice * itemQty))"/>
    </ordertotal>
    

    所有其他元素都可以通过 XSLT 身份转换简单地复制。

    这是完整的 XSLT

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
       <xsl:output method="xml" indent="yes"/>
    
       <xsl:template match="return">
          <xsl:copy>
             <xsl:apply-templates select="@*|node()"/>
             <ordertotal>
                <xsl:value-of select="sum(orderDetails/(itemPrice * itemQty))"/>
             </ordertotal>
          </xsl:copy>
       </xsl:template>
    
       <xsl:template match="@*|node()">
          <xsl:copy>
             <xsl:apply-templates select="@*|node()"/>
          </xsl:copy>
       </xsl:template>
    </xsl:stylesheet>
    

    第一个 return 元素的订单总数应为 17,第二个元素为 52。

    【讨论】:

      猜你喜欢
      • 2010-10-01
      • 2020-05-15
      • 1970-01-01
      • 1970-01-01
      • 2013-04-11
      • 2022-11-18
      • 1970-01-01
      • 1970-01-01
      • 2016-05-22
      相关资源
      最近更新 更多