2010-01-13 95 views
2

我只需要以下文件的<Transaction-Detail>節點(由<tran-id>子節點)進行排序:排序只有特定的XML節點

<TransActDO clear="true" removed="false"> 
    <stmt-reason-code>1001</stmt-reason-code> 
    <Transaction-Detail clear="true" removed="false"> 
    <txn-amt>788.20</txn-amt> 
    <txn-description>New Purchase</txn-description> 
    <tran-id>3271</tran-id> 
    </Transaction-Detail> 
    <Transaction-Detail clear="true" removed="false"> 
    <txn-amt>-68.20</txn-amt> 
    <txn-description>Return</txn-description> 
    <tran-id>27795</tran-id> 
    </Transaction-Detail> 
    <Transaction-Detail clear="true" removed="false"> 
    <txn-amt>0.00</txn-amt> 
    <txn-description>Comment</txn-description> 
    <transaction-reason-desc>No Reason</transaction-reason-desc> 
    <tran-id>13365</tran-id> 
    <transaction-reason-code>0</transaction-reason-code> 
    </Transaction-Detail> 
    <Transaction-Detail clear="true" removed="false"> 
    <txn-amt>343.45</txn-amt> 
    <txn-description>New Purchase</txn-description> 
    <tran-id>7558</tran-id> 
    </Transaction-Detail> 
    <Transaction-Detail clear="true" removed="false"> 
    <txn-amt>0.00</txn-amt> 
    <txn-description>Comment</txn-description> 
    <transaction-reason-desc>No Reason</transaction-reason-desc> 
    <tran-id>6512</tran-id> 
    <transaction-reason-code>0</transaction-reason-code> 
    </Transaction-Detail> 
    <account-no>123456789</account-no> 
    <payer-name>JOHN DOE</payer-name> 
    <Product-Detail clear="true" removed="false"> 
    <Name>WIDGET</Name> 
    <Amount>89.00</Amount> 
    </Product-Detail> 
    <Product-Detail clear="true" removed="false"> 
    <Name>NEWER WIDGET</Name> 
    <Amount>99.99</Amount> 
    </Product-Detail> 
    <stmt-reason-desc>Web Statement</stmt-reason-desc> 
    <type>Original</type> 
</TransActDO> 

輸出是XML,需要同時複製所有其他節點和屬性原始文件。實質上,複製所有內容,只需對Transaction-Detail節點進行排序即可。

我走了這麼遠:

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

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

    <xsl:template match="TransActDO"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*"/> 
     <xsl:apply-templates select="Transaction-Detail"> 
     <xsl:sort select="tran-id" data-type="number" order="ascending"/> 
     </xsl:apply-templates> 
    </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

這將導致一個適當的排序只包含事務的詳細信息節點及其子節點的XML文件。當我試圖添加額外的邏輯來複制其餘的節點時,排序就會中斷。

我想我很難圍繞XSLT執行理論和語法包裝我的大腦。

任何幫助非常感謝!
-nth-

+0

您需要一個preceed設定事務的詳細信息節點的節點保持在頂部和那些遵循保持在底部或付出更多的交易,詳細的節點移動到XMl的底部? (順便說一句,我假設由於遺留的原因,你不能只重新設計XML,使產品詳細信息和交易詳情每個都有一個包含父節點,所以他們沒有不同的標記名的兄弟姐妹) – AnthonyWJones 2010-01-13 22:10:37

回答

4

這將做到這一點: -

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" encoding="Windows-1252" /> 

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

    <xsl:template match="TransActDO"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()[not(preceding-sibling::Transaction-Detail) and not(self::Transaction-Detail)]"/> 
      <xsl:apply-templates select="Transaction-Detail"> 
       <xsl:sort select="tran-id" data-type="number" order="ascending"/> 
      </xsl:apply-templates> 
      <xsl:apply-templates select="@*|node()[not(following-sibling::Transaction-Detail) and not(self::Transaction-Detail)]"/> 
    </xsl:copy> 
    </xsl:template> 


</xsl:stylesheet> 

如果你不介意的移動事務的細節元素的TransActDO元素的頂部或者底部,你可以簡化內部設置的應用模板: -

  <xsl:apply-templates select="@*|node()[not(self::Transaction-Detail)]"/> 
      <xsl:apply-templates select="Transaction-Detail"> 
       <xsl:sort select="tran-id" data-type="number" order="ascending"/> 
      </xsl:apply-templates> 
+0

+1 。我剛剛注意到,你已經發布了我剛剛發佈的*完全相同的*代碼(猜我應該讀你的第二個代碼示例...)。刪除我的答案,以避免冗餘。 – Tomalak 2010-01-14 12:55:23

+0

謝謝安東尼。它確實有效!不幸的是,我不能控制xml結構的創建,但至少可以解決排序問題。 – nth 2010-01-14 15:46:10