2011-07-20 12 views
1

私が特によく構造化されていない在庫システムから出力されたXMLドキュメントがあります。次の<StockSalesRec Type=SH>はそのサプライヤーの製品である前に近接ノードの兄弟に基づいてこのXMLドキュメントを再構築するにはどうすればよいですか?

<root> 
    <StockSalesRec Type="SH">        
     <Reference>A Supplier</Reference>  
     <StockNum></StockNum>      
     <Description></Description> 
     ... 
    </StockSalesRec>           
    <StockSalesRec Type=" ">        
     <Reference>12345</Reference>  
     <StockNum>00001</StockNum>      
     <Description>Item description</Description> 
     ... 
    </StockSalesRec>           
    <StockSalesRec Type=" ">        
     <Reference>67890</Reference>  
     <StockNum>00002</StockNum>      
     <Description>Another description</Description> 
     ... 
    </StockSalesRec> 
    ... 
</root> 

<StockSalesRec Type=SH>は、サプライヤーとすべてです。それはのようなものを見て、この文書を使用する前に、私はそれを再構築したいと思います:

<root> 
    <supplier name="A Supplier"> 
     <product> 
      <Reference>67890</Reference>  
      <StockNum>00002</StockNum>  
      <Description>Another description</Description> 
     </product> 
     .... 
    </supplier> 
    .... 
</root> 

私はこのように文書を変換するに行くかどう?私は解決策としてXSLを使用しようとしましたが、かなり早く立ち往生しました。私は最近Rubyを学んでいるので、それらを使った解決策は素晴らしいだろう。

ありがとう

答えて

1

これは純粋なXSLTソリューションで行うことができると思います。私が最初に(「'のタイプStockSalesRec)すべての製品のためのキーを定義することによって、それを達成ルックアップが最も最近の前の供給業者記録(StockSalesRec参考されていますタイプ 'SH')の

<xsl:key 
    name="Stock" 
    match="StockSalesRec[@Type=' ']" 
    use="(preceding-sibling::StockSalesRec[@Type='SH'])[last()]/Reference" /> 
あなたがそのように

<xsl:apply-templates select="StockSalesRec[@Type='SH']" /> 

のように、すべてのサプライヤ・ノードに一致させることができます

そして、あなたのサンプルXMLにこれを適用すると、その後、そのような各サプライヤ・ノードのために、あなたは....以前

これは完全に与え置く
<xsl:apply-templates select="key('Stock', Reference)" /> 

定義されたキーを使用して、すべての製品のレコードを

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

    <xsl:key 
     name="Stock" 
     match="StockSalesRec[@Type=' ']" 
     use="(preceding-sibling::StockSalesRec[@Type='SH'])[last()]/Reference"/> 

    <xsl:template match="/root"> 
     <xsl:copy> 
     <xsl:apply-templates select="StockSalesRec[@Type='SH']"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="StockSalesRec[@Type='SH']"> 
     <supplier name="{Reference}"> 
     <xsl:apply-templates select="key('Stock', Reference)"/> 
     </supplier> 
    </xsl:template> 

    <xsl:template match="StockSalesRec[@Type=' ']"> 
     <product> 
     <xsl:apply-templates/> 
     </product> 
    </xsl:template> 

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

</xsl:stylesheet> 

を読むことができます出力は以下の通りである。

<root> 
    <supplier name="A Supplier"> 
     <product> 
     <Reference>12345</Reference> 
     <StockNum>00001</StockNum> 
     <Description>Item description</Description> 
     </product> 
     <product> 
     <Reference>67890</Reference> 
     <StockNum>00002</StockNum> 
     <Description>Another description</Description> 
     </product> 
    </supplier> 
</root> 

は、製品のノードを作成する際に変換する余分な子要素が変更することなく、入力XMLに追加することができるアイデンティティの使用を注意してください。 XSLT

+0

これは素晴らしいです!非常によく説明され、非常にありがとう。 – Jamie

関連する問題