2016-02-09 88 views
1

我對XSLT相當陌生,以前從未使用過Muenchian分組。我一直試圖通過爲自己創建一個樣本來理解概念,但我無法理解如何獲得所需的輸出,特別是在處理子記錄時。XSLT和Muenchian分組,多級樣本

比方說,我們有一個輸入XML,看起來像這樣:

<OrdersFF xmlns="http://Romp.BizTalk.MapTest"> 
    <Order> 
    <OrderID>O1</OrderID> 
    <ItemID>I1</ItemID> 
    <TrackingID>T1</TrackingID> 
    </Order> 
    <Order> 
    <OrderID>O1</OrderID> 
    <ItemID>I2</ItemID> 
    <TrackingID>T2</TrackingID> 
    </Order> 
    <Order> 
    <OrderID>O1</OrderID> 
    <ItemID>I2</ItemID> 
    <TrackingID>T3</TrackingID> 
    </Order> 
    <Order> 
    <OrderID>O2</OrderID> 
    <ItemID>I3</ItemID> 
    <TrackingID>T4</TrackingID> 
    </Order> 
    <Order> 
    <OrderID>O2</OrderID> 
    <ItemID>I3</ItemID> 
    <TrackingID>T5</TrackingID> 
    </Order> 
    <Order> 
    <OrderID>O3</OrderID> 
    <ItemID>I4</ItemID> 
    <TrackingID>T6</TrackingID> 
    </Order> 
</OrdersFF> 

而且我們想通過訂單ID,然後項目輸出到組,然後trackingcode(我們假設每個訂單可以有多個項目,每個項目可以有多個跟蹤代碼)。所以輸出應該是這樣的:

<ns0:orders xmlns:ns0="http://Romp.BizTalk.MapTest"> 
    <order> 
    <orderid>O1</orderid> 
    <items> 
     <item>I1</item> 
     <shippingdetails> 
     <trackingcode>T1</trackingcode> 
     </shippingdetails> 
    </items> 
    <items> 
     <item>I2</item> 
     <shippingdetails> 
     <trackingcode>T2</trackingcode> 
     </shippingdetails> 
     <shippingdetails> 
     <trackingcode>T3</trackingcode> 
     </shippingdetails> 
    </items> 
    </order> 
    <order> 
    <orderid>O2</orderid> 
    <items> 
     <item>I3</item> 
     <shippingdetails> 
     <trackingcode>T4</trackingcode> 
     </shippingdetails> 
     <shippingdetails> 
     <trackingcode>T5</trackingcode> 
     </shippingdetails> 
    </items> 
    </order> 
    <order> 
    <orderid>O3</orderid> 
    <items> 
     <item>I4</item> 
     <shippingdetails> 
     <trackingcode>T6</trackingcode> 
     </shippingdetails> 
    </items> 
    </order> 
</ns0:orders> 

我試圖用XSLT玩了,這是我至今(不工作):

<?xml version="1.0" encoding="UTF-16"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var" exclude-result-prefixes="msxsl var s0" version="1.0" xmlns:s0="http://Romp.BizTalk.MapTest" xmlns:ns0="http://Romp.BizTalk.MapTest"> 
    <xsl:output omit-xml-declaration="yes" method="xml" version="1.0" /> 

    <!-- Create a key to match against groups in source schema --> 
    <xsl:key name="k1" match="Order" use="OrderID"/> 

    <xsl:key name="k2" match="Order" use="concat(OrderID,'|',ItemID)"/> 

    <xsl:key name="k3" match="Order" use="concat(OrderID,'|',ItemID,'|',TrackingID)"/> 


    <xsl:template match="/"> 
    <xsl:apply-templates select="/s0:OrdersFF" /> 
    </xsl:template> 

    <xsl:template match="/s0:OrdersFF"> 
    <ns0:orders> 

     <!-- This will loop through our key ("OrderID") --> 
     <xsl:for-each select="Order[generate-id(.)=generate-id(key('k1',OrderID))]"> 

     <order> 
      <orderid> 
      <xsl:value-of select="OrderID/text()" /> 
      </orderid> 

      <!-- Another loop... --> 
      <xsl:for-each select="Order[generate-id(.)=generate-id(key('k2',concat(OrderID,'|',ItemID)))]"> 
      <items> 
       <item> 
       <xsl:value-of select="ItemID" /> 
       </item> 

       <!-- Another loop... --> 
       <xsl:for-each select="Order[generate-id(.)=generate-id(key('k3',concat(OrderID,'|',ItemID,'|',TrackingID)))]"> 
       <shippingdetails> 
        <trackingcode> 
        <xsl:value-of select="TrackingID"/> 
        </trackingcode> 
       </shippingdetails> 
       </xsl:for-each> 

      </items> 
      </xsl:for-each> 



     </order> 

     </xsl:for-each> 

    </ns0:orders> 
    </xsl:template> 
</xsl:stylesheet> 

任何人都可以請您提供有關如何進行的任何幫助? 謝謝!

回答

2

對於XSLT來說,你並不是那麼遙遠,這是一個非常好的開始,但有兩個問題需要糾正。第一個是命名空間。您正在處理某些地方的命名空間,例如...

<xsl:apply-templates select="/s0:OrdersFF" /> 

但並非在所有地方。在您的情況下,前綴s0需要在XSLT中的所有元素名稱前綴,包括它們出現在鍵中的時間。例如

<xsl:key name="k2" match="s0:Order" use="concat(s0:OrderID,'|',s0:ItemID)"/> 

第二個問題是你的巢循環。第一個嵌套的循環看起來像這樣(後我加入了命名空間前綴,這是)

<xsl:for-each select="s0:Order[generate-id(.)=generate-id(key('k2',concat(s0:OrderID,'|',s0:ItemID)))]"> 

但您目前位於該點的Order元素,所以這是尋找孩子的那Order元素,不存在!你需要做的是選擇當前「組」中的所有Order元素。而要做到這一點,您可以使用以前的密鑰

<xsl:for-each select="key('k1',s0:OrderID)[generate-id(.)=generate-id(key('k2',concat(s0:OrderID,'|',s0:ItemID)))]"> 

同樣,對於嵌套在該for-each

試試這個稍作修改XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var" exclude-result-prefixes="msxsl var s0" version="1.0" xmlns:s0="http://Romp.BizTalk.MapTest" xmlns:ns0="http://Romp.BizTalk.MapTest"> 
    <xsl:output omit-xml-declaration="yes" method="xml" version="1.0" indent="yes" /> 

    <!-- Create a key to match against groups in source schema --> 
    <xsl:key name="k1" match="s0:Order" use="s0:OrderID"/> 

    <xsl:key name="k2" match="s0:Order" use="concat(s0:OrderID,'|',s0:ItemID)"/> 

    <xsl:key name="k3" match="s0:Order" use="concat(s0:OrderID,'|',s0:ItemID,'|',s0:TrackingID)"/> 

    <xsl:template match="/"> 
    <xsl:apply-templates select="/s0:OrdersFF" /> 
    </xsl:template> 

    <xsl:template match="/s0:OrdersFF"> 
    <ns0:orders> 

     <!-- This will loop through our key ("OrderID") --> 
     <xsl:for-each select="s0:Order[generate-id(.)=generate-id(key('k1',s0:OrderID))]"> 

     <order> 
      <orderid> 
      <xsl:value-of select="s0:OrderID/text()" /> 
      </orderid> 

      <!-- Another loop... --> 
      <xsl:for-each select="key('k1',s0:OrderID)[generate-id(.)=generate-id(key('k2',concat(s0:OrderID,'|',s0:ItemID)))]"> 
      <items> 
       <item> 
       <xsl:value-of select="s0:ItemID" /> 
       </item> 

       <!-- Another loop... --> 
       <xsl:for-each select="key('k2',concat(s0:OrderID,'|',s0:ItemID))[generate-id(.)=generate-id(key('k3',concat(s0:OrderID,'|',s0:ItemID,'|',s0:TrackingID)))]"> 
       <shippingdetails> 
        <trackingcode> 
        <xsl:value-of select="s0:TrackingID"/> 
        </trackingcode> 
       </shippingdetails> 
       </xsl:for-each> 

      </items> 
      </xsl:for-each> 
     </order> 
     </xsl:for-each> 
    </ns0:orders> 
    </xsl:template> 
</xsl:stylesheet> 
+0

謝謝你這麼多詳細的說明!你的回答非常有用! :) – Steven