2013-02-18 48 views
1

下面給出了請求XML,並給出了我正在使用的XSLT轉換。xslt 1.0更新正確的標頭

不幸的是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> 
+0

我已經看到了他們兩人之間的差異,但下一次我認爲最好把所有事情都放在一個問題上。他們太相似了...... – 2013-02-18 12:11:05

+0

不知道爲什麼突然之間這個老問題被拒絕投了 – Joe2013 2013-03-12 04:48:21

+0

@downvoter - 這個問題出了什麼問題。 – Joe2013 2013-03-12 08:46:36

回答

3

你必須遵循從你這裏張貼的問題同樣的想法:XSLT - Updating the Header

而是匹配結果,匹配的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> 

然後你可以從計算,總模板中刪除默認值第一個參數,除去選擇=「訂單明細」屬性。

此外,因爲您沒有使用元素複製的,您必須將身份模板更改爲:

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