2011-01-12 5 views
1

xsltを使用してXMLを変換する必要があります。子要素の値とシーケンス番号に基づいて親ノードをグループ化する

ロジック:

スプリット親が別の子アドレスを持つと親の名前にシーケンス番号を追加する場合は、親。また、子供の行番号が必要です。 ここでは親ノードの数があり、各親ノードにはより多くの子ノードがあります。

私はこれを達成するためにさまざまな方法を試しましたが、私はforeach内でシーケンス番号を生成することに固執しています。だから誰もがこれを解決しようとすることができます。以下のように

ソースXML:

<Data> 
    <Parent> 
     <Name>P1</Name> 
     <Child> 
     <Name>CName1</Name> 
     <Address>Address1</Address> 
     </Child> 
     <Child> 
     <Name>CName2</Name> 
     <Address>Address2</Address> 
     </Child> 
     <Child> 
     <Name>CName3</Name> 
     <Address>Address1</Address> 
     </Child> 
    </Parent> 

    <Parent> 
    <Name>P2</Name> 
     <Child> 
     <Name>CName1</Name> 
     <Address>Address1</Address> 
     </Child> 
    </Parent> 
</Data> 

ターゲットXMLは以下のようにする必要があります:

<Data> 
    <Parent> 
    <Name>P1_1</Name> 
    <Address>Address1</Address> 
    <Child> 
     <LineNumber>1</LineNumber> 
     <Name>CName1</Name> 
    </Child> 
    <Child> 
     <LineNumber>2</LineNumber> 
     <Name>CName3</Name> 
    </Child> 
    </Parent> 

    <Parent> 
     <Name>P1_2</Name> 
     <Address>Address2</Address> 
     <Child> 
     <LineNumber>1</LineNumber> 
     <Name>CName2</Name> 
     </Child> 
    </Parent> 

    <Parent> 
     <Name>P2_1</Name> 
     <Address>Address1</Address> 
     <Child> 
      <LineNumber>1</LineNumber> 
      <Name>CName1</Name> 
     </Child> 
    </Parent> 
</Data> 
+0

{}ボタンを使用してコードを書式設定してください。 – bluish

+0

グループ化の問題については、XSLT 2.0を使用できるかどうか、XSLT 1.0に固執しているかどうかを教えてください。グループ化は、2.0では* MUCH *より簡単です。また、問題の一部(グループ分け)を解決して他の部分(番号付け)にぶつかった場合は、どれだけ手を伸ばしているかを示すことができます。誤った。 –

答えて

3

このXSLT 1.0変換:

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

    <xsl:key name="kAddress" match="Child" use="concat(generate-id(..), '|', Address)" /> 

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

    <xsl:template match="Parent"> 
    <xsl:variable name="parent" select="." /> 
    <xsl:for-each select="Child[ 
     generate-id() 
     = 
     generate-id(key('kAddress', concat(generate-id($parent), '|', Address))[1]) 
    ]"> 
     <Parent> 
     <Name><xsl:value-of select="concat(../Name, '_', position())" /></Name> 
     <xsl:copy-of select="Address" /> 
     <xsl:apply-templates select=" 
      key('kAddress', concat(generate-id($parent), '|', Address)) 
     " /> 
     </Parent> 
    </xsl:for-each> 
    </xsl:template> 

    <xsl:template match="Child"> 
    <xsl:copy> 
     <xsl:copy-of select="@*" /> 
     <LineNumber><xsl:value-of select="position()" /></LineNumber> 
     <xsl:apply-templates select="node()[not(self::Address)]" /> 
    </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

はあなたのサンプルについては、以下の出力を生成します:

<Data> 
    <Parent> 
     <Name>P1_1</Name> 
     <Address>Address1</Address> 
     <Child> 
      <LineNumber>1</LineNumber> 
      <Name>CName1</Name> 
     </Child> 
     <Child> 
      <LineNumber>2</LineNumber> 
      <Name>CName3</Name> 
     </Child> 
    </Parent> 
    <Parent> 
     <Name>P1_2</Name> 
     <Address>Address2</Address> 
     <Child> 
      <LineNumber>1</LineNumber> 
      <Name>CName2</Name> 
     </Child> 
    </Parent> 
    <Parent> 
     <Name>P2_1</Name> 
     <Address>Address1</Address> 
     <Child> 
      <LineNumber>1</LineNumber> 
      <Name>CName1</Name> 
     </Child> 
    </Parent> 
</Data> 
+0

+1正解です。 –

+0

+1。すべて正しい。 – Flack

+0

+1読みやすくするために親と住所でチャイルドを使用する –

関連する問題