我需要通过添加订单价格的总和将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>
我需要在计算广告添加后将其转换为以下格式吗?元素。转换后的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>
XSLT2.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>
如果您使用XSLT1.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>
您已经标记了问题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个订单总数。