1

下面给出了我的请求 XML,还给出了我正在使用的 XSLT 转换。

不幸的是,该ordertotal元素在转换后重复了两次。如何更新ordertotal元素而不是重复它?

请求 XML 是

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
      <ns2:fetchOrderListResponse xmlns:ns2="http://impl.lob.wipro.com/">
         <return>
            <customerOrderNumber>1</customerOrderNumber>
            <orderDetails>
               <itemPrice>50.0</itemPrice>
               <itemQty>2</itemQty>
               <itemUnit>0</itemUnit>
               <orderDetailsId>37516016-D71B-4790-951F-55D00B0CC159</orderDetailsId>
               <camelAddedDtlField>0.1</camelAddedDtlField>
            </orderDetails>
            <orderDetails>
               <itemPrice>39.0</itemPrice>
               <itemQty>3</itemQty>
               <itemUnit>0</itemUnit>
               <orderDetailsId>6095ABC7-0D0D-4B2E-92E5-80F24E9092B8</orderDetailsId>
               <camelAddedDtlField>0.1</camelAddedDtlField>
            </orderDetails>
            <orderId>84EC371D-40CA-455E-A0FA-7EA733E9BFD3</orderId>
            <ordertotal>0.0</ordertotal>
            <camelAddedHdrField>0.0</camelAddedHdrField>
         </return>
         <return>
            <customerOrderNumber>1</customerOrderNumber>
            <orderId>54712493-2172-4ADB-814B-BC7AA0BB72C3</orderId>
            <ordertotal>0.0</ordertotal>
            <camelAddedHdrField>0.0</camelAddedHdrField>
         </return>
         <return>
            <customerOrderNumber>1</customerOrderNumber>
            <deliverydate>2013-02-06T00:00:00+05:30</deliverydate>
            <orderDetails>
               <itemPrice>565.0</itemPrice>
               <itemQty>1</itemQty>
               <itemUnit>0</itemUnit>
               <orderDetailsId>9A5030BE-F95F-4C62-B5A2-41FF85423218</orderDetailsId>
               <camelAddedDtlField>0.1</camelAddedDtlField>
            </orderDetails>
            <orderDetails>
               <itemPrice>4.0</itemPrice>
               <itemQty>90</itemQty>
               <itemUnit>0</itemUnit>
               <orderDetailsId>65A8B3BE-D407-43D8-8754-EA1E26AA56E4</orderDetailsId>
               <camelAddedDtlField>0.1</camelAddedDtlField>
            </orderDetails>
            <orderId>0BDCB222-0117-47A9-8813-DF03A1D19E5E</orderId>
            <ordertotal>0.0</ordertotal>
            <camelAddedHdrField>0.0</camelAddedHdrField>
         </return>
         <return>
            <customerOrderNumber>1</customerOrderNumber>
            <orderId>8E4220DC-884B-47BC-A565-E26B80BA5249</orderId>
            <ordertotal>0.0</ordertotal>
            <camelAddedHdrField>0.0</camelAddedHdrField>
         </return>
         <return>
            <customerOrderNumber>1</customerOrderNumber>
            <deliverydate>2013-02-06T00:00:00+05:30</deliverydate>
            <orderDetails>
               <itemPrice>10.0</itemPrice>
               <itemQty>4</itemQty>
               <itemUnit>0</itemUnit>
               <orderDetailsId>5A2DF895-BB0F-4039-80DB-F44CED31697B</orderDetailsId>
               <camelAddedDtlField>0.1</camelAddedDtlField>
            </orderDetails>
            <orderDetails>
               <itemPrice>20.0</itemPrice>
               <itemQty>3</itemQty>
               <itemUnit>0</itemUnit>
               <orderDetailsId>8034FBF4-B573-4B19-BDF5-FAF6C4247A55</orderDetailsId>
               <camelAddedDtlField>0.1</camelAddedDtlField>
            </orderDetails>
            <orderId>60161E3E-3C4A-4CE6-AAC3-E4D2BC240046</orderId>
            <ordertotal>0.0</ordertotal>
            <camelAddedHdrField>0.0</camelAddedHdrField>
         </return>
      </ns2:fetchOrderListResponse>
   </soap:Body>
</soap:Envelope>

XSLT 是

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

响应 XML 显示重复标记是

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
      <ns2:fetchOrderListResponse xmlns:ns2="http://impl.lob.wipro.com/">

         <return>
            <customerOrderNumber>1</customerOrderNumber>
            <orderDetails>
               <itemPrice>50.0</itemPrice>
               <itemQty>2</itemQty>
               <itemUnit>0</itemUnit>
               <orderDetailsId>37516016-D71B-4790-951F-55D00B0CC159</orderDetailsId>
               <camelAddedDtlField>0.1</camelAddedDtlField>
            </orderDetails>
            <orderDetails>
               <itemPrice>39.0</itemPrice>
               <itemQty>3</itemQty>
               <itemUnit>0</itemUnit>
               <orderDetailsId>6095ABC7-0D0D-4B2E-92E5-80F24E9092B8</orderDetailsId>
               <camelAddedDtlField>0.1</camelAddedDtlField>
            </orderDetails>
            <orderId>84EC371D-40CA-455E-A0FA-7EA733E9BFD3</orderId>
            <ordertotal>0.0</ordertotal>
            <camelAddedHdrField>0.0</camelAddedHdrField>
            <ordertotal>217</ordertotal>
         </return>
         <return>
            <customerOrderNumber>1</customerOrderNumber>
            <orderId>54712493-2172-4ADB-814B-BC7AA0BB72C3</orderId>
            <ordertotal>0.0</ordertotal>
            <camelAddedHdrField>0.0</camelAddedHdrField>
            <ordertotal>0</ordertotal>
         </return>
         <return>
            <customerOrderNumber>1</customerOrderNumber>
            <deliverydate>2013-02-06T00:00:00+05:30</deliverydate>
            <orderDetails>
               <itemPrice>565.0</itemPrice>
               <itemQty>1</itemQty>
               <itemUnit>0</itemUnit>
               <orderDetailsId>9A5030BE-F95F-4C62-B5A2-41FF85423218</orderDetailsId>
               <camelAddedDtlField>0.1</camelAddedDtlField>
            </orderDetails>
            <orderDetails>
               <itemPrice>4.0</itemPrice>
               <itemQty>90</itemQty>
               <itemUnit>0</itemUnit>
               <orderDetailsId>65A8B3BE-D407-43D8-8754-EA1E26AA56E4</orderDetailsId>
               <camelAddedDtlField>0.1</camelAddedDtlField>
            </orderDetails>
            <orderId>0BDCB222-0117-47A9-8813-DF03A1D19E5E</orderId>
            <ordertotal>0.0</ordertotal>
            <camelAddedHdrField>0.0</camelAddedHdrField>
            <ordertotal>925</ordertotal>
         </return>
         <return>
            <customerOrderNumber>1</customerOrderNumber>
            <orderId>8E4220DC-884B-47BC-A565-E26B80BA5249</orderId>
            <ordertotal>0.0</ordertotal>
            <camelAddedHdrField>0.0</camelAddedHdrField>
            <ordertotal>0</ordertotal>
         </return>
         <return>
            <customerOrderNumber>1</customerOrderNumber>
            <deliverydate>2013-02-06T00:00:00+05:30</deliverydate>
            <orderDetails>
               <itemPrice>10.0</itemPrice>
               <itemQty>4</itemQty>
               <itemUnit>0</itemUnit>
               <orderDetailsId>5A2DF895-BB0F-4039-80DB-F44CED31697B</orderDetailsId>
               <camelAddedDtlField>0.1</camelAddedDtlField>
            </orderDetails>
            <orderDetails>
               <itemPrice>20.0</itemPrice>
               <itemQty>3</itemQty>
               <itemUnit>0</itemUnit>
               <orderDetailsId>8034FBF4-B573-4B19-BDF5-FAF6C4247A55</orderDetailsId>
               <camelAddedDtlField>0.1</camelAddedDtlField>
            </orderDetails>
            <orderId>60161E3E-3C4A-4CE6-AAC3-E4D2BC240046</orderId>
            <ordertotal>0.0</ordertotal>
            <camelAddedHdrField>0.0</camelAddedHdrField>
            <ordertotal>100</ordertotal>
         </return>
      </ns2:fetchOrderListResponse>
   </soap:Body>
</soap:Envelope>
4

1 回答 1

3

您必须遵循您在此处发布的问题的相同想法:XSLT - 更新标题

不匹配结果,而是匹配 ordertotal 并更改 XPath 表达式以选择 orderDetails 元素。

所以,改变这个:

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

到:

<xsl:template match="ordertotal">
    <xsl:copy>
        <xsl:call-template name="calculate-total">
            <xsl:with-param name="orderDetails"
                            select="../orderDetails" />
        </xsl:call-template>
    </xsl:copy>
</xsl:template>

然后,您可以从计算总计模板中删除第一个参数的默认值,删除 select="orderDetails" 属性。

此外,因为您没有使用 copy-of 元素,您必须将标识模板更改为:

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

所以完整的样式表将是:

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

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

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

    <xsl:template match="ordertotal">
        <xsl:copy>
            <xsl:call-template name="calculate-total">
                <xsl:with-param name="orderDetails"
                                select="../orderDetails" />
            </xsl:call-template>
        </xsl:copy>
    </xsl:template>

    <xsl:template name="calculate-total">
        <xsl:param name="orderDetails" />
        <xsl:param name="total"
                   select="'0'" />

        <xsl:choose>
            <xsl:when test="$orderDetails">
                <xsl:call-template name="calculate-total">
                    <xsl:with-param name="orderDetails"
                                    select="$orderDetails[position() > 1]" />
                    <xsl:with-param name="total"
                                    select="$total + ($orderDetails[1]/itemPrice * $orderDetails[1]/itemQty)" />
                </xsl:call-template>        
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$total" />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>
于 2013-02-18T11:59:12.193 回答