2011-10-13 57 views
0

我正在以下面定義的格式接收XML。我正在編寫一些代碼來轉換XML,只有特定的節點纔會變平。XSLT將扁平化特定的XML節點

<TransactionRequest> 
    <OrderRequests> 
    <OrderRequest> 
     <ReferenceNumber>1234567</ReferenceNumber> 
     <TransactionTime>2010-11-16T00:00:00-08:00</TransactionTime> 
     <IsRush>true</IsRush> 
     <ShippingAddress> 
     <Name>Tom Hanks</Name> 
     <Address1>1123 Canada Way</Address1> 
     <City>Burnaby</City> 
     <Province>BC</Province> 
     <PostalCode>V3B13B</PostalCode> 
     <HomePhone>6048871121</HomePhone> 
     <BusinessPhone>6041232342</BusinessPhone> 
     </ShippingAddress> 
     <ProgramType>C2</ProgramType> 
     <Comments>Deliver to the receptionist</Comments> 
     <Items> 
     <Item> 
      <Sku>UN10004</Sku> 
      <Quantity>2</Quantity> 
     </Item> 
     <Item> 
      <Sku>UN980011</Sku> 
      <Quantity>1</Quantity> 
     </Item> 
     </Items> 
    </OrderRequest> 
    </OrderRequests> 
    <TraceRequests> 
    <TraceRequest> 
     <ReferenceNumber>23432345</ReferenceNumber> 
     <TransactionTime>2010-11-16T00:00:00-08:00</TransactionTime> 
     <OriginalReferenceNumber>1234567</OriginalReferenceNumber> 
     <Comments>Trace Items</Comments> 
     <TraceItems> 
     <TraceItem> 
      <Sku>UN10004</Sku> 
      <Quantity>2</Quantity> 
      <ShipmentNumber>CM88888990</ShipmentNumber> 
     </TraceItem> 
     <TraceItem> 
      <Sku>UN980011</Sku> 
      <ProductCode>AA0091</ProductCode> 
      <Quantity>1</Quantity> 
      <ShipmentNumber>DDP123123123</ShipmentNumber> 
     </TraceItem> 
     </TraceItems> 
    </TraceRequest> 
    </TraceRequests> 
</TransactionRequest> 

我希望結果看起來像下面的XML。不同的是,在這個XML中,通過爲每個Items/Item複製父信息一次,TraceRequest節點將每個Items/Item節點拆分一個節點。

<?xml version="1.0"?> 
<TransactionRequest> 
    <OrderRequests> 
    <OrderRequest> 
     <ReferenceNumber>1234567</ReferenceNumber> 
     <TransactionTime>2010-11-16T00:00:00-08:00</TransactionTime> 
     <IsRush>true</IsRush> 
     <ShippingAddress> 
     <Name>Tom Hanks</Name> 
     <Address1>1123 Canada Way</Address1> 
     <City>Burnaby</City> 
     <Province>BC</Province> 
     <PostalCode>V3B13B</PostalCode> 
     <HomePhone>6048871121</HomePhone> 
     <BusinessPhone>6041232342</BusinessPhone> 
     </ShippingAddress> 
     <ProgramType>C2</ProgramType> 
     <Comments>Deliver to the receptionist</Comments> 
     <Items> 
     <Item> 
      <Sku>UN10004</Sku> 
      <Quantity>2</Quantity> 
     </Item> 
     <Item> 
      <Sku>UN980011</Sku> 
      <Quantity>1</Quantity> 
     </Item> 
     </Items> 
    </OrderRequest> 
    </OrderRequests> 
    <TraceRequests> 
    <TraceRequest> 
     <ReferenceNumber>23432345</ReferenceNumber> 
     <TransactionTime>2010-11-16T00:00:00-08:00</TransactionTime> 
     <OriginalReferenceNumber>1234567</OriginalReferenceNumber> 
     <Comments>Trace Items</Comments> 
     <Sku>UN10004</Sku> 
     <Quantity>2</Quantity> 
     <ShipmentNumber>CM88888990</ShipmentNumber> 
    </TraceRequest> 
    <TraceRequest> 
     <ReferenceNumber>23432345</ReferenceNumber> 
     <TransactionTime>2010-11-16T00:00:00-08:00</TransactionTime> 
     <OriginalReferenceNumber>1234567</OriginalReferenceNumber> 
     <Comments>Trace Items</Comments> 
     <Sku>UN980011</Sku> 
     <ProductCode>AA0091</ProductCode> 
     <Quantity>1</Quantity> 
     <ShipmentNumber>DDP123123123</ShipmentNumber> 
    </TraceRequest> 
    </TraceRequests> 
</TransactionRequest> 

我似乎無法生成一個XSLT來只展平TraceRequest元素的特定子節點元素。

回答

2

您可以通過使用特殊情況下的額外模板重寫標準身份轉換來完成此操作。

首先,當你匹配一個TraceRequest節點,你那麼想直接跳到匹配TraceItem節點,在那裏你會做複製。在這種情況下,可以將當前的TraceRequest節點作爲參數傳入,以便稍後複製其chidlren。

<xsl:template match="TraceRequest"> 
    <xsl:apply-templates select="TraceItems/TraceItem"> 
     <xsl:with-param name="TraceRequestNode" select="."/> 
    </xsl:apply-templates> 
</xsl:template> 

然後,匹配TraceItem時,你可以只複製TraceRequest通過參數(不包括TraceItems節點)傳入的孩子,也是在TraceItem節點的孩子你目前的位置。

<xsl:template match="TraceItem"> 
    <xsl:param name="TraceRequestNode"/> 
    <TraceRequest> 
     <xsl:apply-templates select="$TraceRequestNode/*[not(self::TraceItems)]"/> 
     <xsl:apply-templates select="@*|node()"/> 
    </TraceRequest> 
</xsl:template> 

因此,給予了充分的XSLT:

<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="TraceRequest"> 
     <xsl:apply-templates select="TraceItems/TraceItem"> 
     <xsl:with-param name="TraceRequestNode" select="."/> 
     </xsl:apply-templates> 
    </xsl:template> 

    <xsl:template match="TraceItem"> 
     <xsl:param name="TraceRequestNode"/> 
     <TraceRequest> 
     <xsl:apply-templates select="$TraceRequestNode/*[not(self::TraceItems)]"/> 
     <xsl:apply-templates select="@*|node()"/> 
     </TraceRequest> 
    </xsl:template> 
</xsl:stylesheet> 

當適用於您的示例XML,輸出如下:

<TransactionRequest> 
    <OrderRequests> 
     <OrderRequest> 
     <ReferenceNumber>1234567</ReferenceNumber> 
     <TransactionTime>2010-11-16T00:00:00-08:00</TransactionTime> 
     <IsRush>true</IsRush> 
     <ShippingAddress> 
      <Name>Tom Hanks</Name> 
      <Address1>1123 Canada Way</Address1> 
      <City>Burnaby</City> 
      <Province>BC</Province> 
      <PostalCode>V3B13B</PostalCode> 
      <HomePhone>6048871121</HomePhone> 
      <BusinessPhone>6041232342</BusinessPhone> 
     </ShippingAddress> 
     <ProgramType>C2</ProgramType> 
     <Comments>Deliver to the receptionist</Comments> 
     <Items> 
      <Item> 
       <Sku>UN10004</Sku> 
       <Quantity>2</Quantity> 
      </Item> 
      <Item> 
       <Sku>UN980011</Sku> 
       <Quantity>1</Quantity> 
      </Item> 
     </Items> 
     </OrderRequest> 
    </OrderRequests> 
    <TraceRequests> 
     <TraceRequest> 
     <ReferenceNumber>23432345</ReferenceNumber> 
     <TransactionTime>2010-11-16T00:00:00-08:00</TransactionTime> 
     <OriginalReferenceNumber>1234567</OriginalReferenceNumber> 
     <Comments>Trace Items</Comments> 
     <Sku>UN10004</Sku> 
     <Quantity>2</Quantity> 
     <ShipmentNumber>CM88888990</ShipmentNumber> 
     </TraceRequest> 
     <TraceRequest> 
     <ReferenceNumber>23432345</ReferenceNumber> 
     <TransactionTime>2010-11-16T00:00:00-08:00</TransactionTime> 
     <OriginalReferenceNumber>1234567</OriginalReferenceNumber> 
     <Comments>Trace Items</Comments> 
     <Sku>UN980011</Sku> 
     <ProductCode>AA0091</ProductCode> 
     <Quantity>1</Quantity> 
     <ShipmentNumber>DDP123123123</ShipmentNumber> 
     </TraceRequest> 
    </TraceRequests> 
</TransactionRequest> 
0

好吧,我想我回答了我的問題bu運行下面的XSLT:

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

    <xsl:template match="TransactionRequest"> 
    <TransactionRequest> 
     <xsl:copy-of select="OrderRequests"/> 
     <TraceRequests> 
     <xsl:for-each select="TraceRequests/TraceRequest/TraceItems/TraceItem"> 
      <TraceRequest> 
      <xsl:copy-of select="../../ReferenceNumber"/> 
      <xsl:copy-of select="../../TransactionTime"/> 
      <xsl:copy-of select="../../OriginalReferenceNumber"/> 
      <xsl:copy-of select="../../Comments"/> 

      <xsl:copy-of select="Sku"/> 
      <xsl:copy-of select="Quantity"/> 
      <xsl:copy-of select="ShipmentNumber"/> 
      <xsl:copy-of select="ProductCode"/> 
      <xsl:copy-of select="DropShipPoNumber"/> 
      </TraceRequest> 
     </xsl:for-each> 
     </TraceRequests> 
    </TransactionRequest> 
    </xsl:template> 
</xsl:stylesheet>