2017-11-19 15 views
0

同じ属性値を持ちながら内容が異なる兄弟ノードを含むXMLがあります。これは以下のように、親と子のレベルの両方で発生します。親ノードが特定の(未知の)値を持つ子ノードを結合するXSLT

<myxml> 
    <a myattr="valuetop1"> 
     <b myattr="valuechild1"> 
      <c>Stuff1</c> 
      <c>Stuff2</c> 
     </b> 
    </a> 
    <a myattr="valuetop1"> 
     <b myattr="valuechild2"> 
      <c>Stuff3</c> 
     </b> 
    </a> 
    <a myattr="valuetop1"> 
     <b myattr="valuechild2"> 
      <c>Stuff4</c> 
     </b> 
    </a> 
    <a myattr="valuetop1"> 
     <b myattr="valuechild2"> 
      <c>Stuff5</c> 
      <c>Stuff6</c> 
     </b> 
    </a> 
    <a myattr="valuetop2"> 
     <b myattr="valuechild1"> 
      <c>Stuff1</c> 
     </b> 
    </a> 
    <a myattr="valuetop2"> 
     <b myattr="valuechild3"> 
      <c>Stuff2</c> 
     </b> 
    </a> 
    <a myattr="valuetop2"> 
     <b myattr="valuechild2"> 
      <c>Stuff3</c> 
      <c>Stuff2</c> 
     </b> 
    </a> 
    <a myattr="valuetop2"> 
     <b myattr="valuechild2"> 
      <c>Stuff4</c> 
     </b> 
    </a> 
</myxml> 

同じレベルに存在し、同一の属性値を持つノードが存在する場合、私はそのノードの単一のインスタンスの下にその内容をまとめたいです。言い換えれば、私はこのようなきちんとした階層を探しています:

<myxml> 
    <a myattr="valuetop1"> 
     <b myattr="valuechild1"> 
      <c>Stuff1</c> 
      <c>Stuff2</c> 
     </b> 
     <b myattr="valuechild2"> 
      <c>Stuff3</c> 
      <c>Stuff4</c> 
      <c>Stuff5</c> 
      <c>Stuff6</c> 
     </b> 
    </a>   
    <a myattr="valuetop2"> 
     <b myattr="valuechild1"> 
      <c>Stuff1</c> 
     </b> 
     <b myattr="valuechild3"> 
      <c>Stuff2</c> 
     </b> 
     <b myattr="valuechild2"> 
      <c>Stuff3</c> 
      <c>Stuff2</c> 
      <c>Stuff4</c> 
     </b> 
    </a>  
</myxml> 

キャッチは私はvaluetopxまたはvaluechildxの値はがどうなるか分からないということです。私は数日間この頭の上に頭を叩いていましたが、その周りに私の脳を得ることはできません。

+0

[**なぜ「それのまわりで私の脳を取得することはできません実際の質問ではありませんか?**](https://meta.stackoverflow.com/q/284236/290085) – kjhughes

+1

ここに実際にあるのは、グループ化の問題です。 XSLT 1.0を使用している場合は、Muenchian Grouping(http://www.jenitennison.com/xslt/grouping/muenchian.htmlを参照)で読んでください。 XSLT 2.0を使用している場合は、xsl:for-each-groupを読んでください。 –

+0

@TimCまともな答えのようです。あなたは1つを作りたいですか?私は未回答の質問のリストからこれを得ることに感謝します。 – Yunnosch

答えて

1

コメントに記載されているように、XSLT 1.0ではMuenchian Groupingというテクニックを使用できますが、あなたの場合は2段階で行います。

親のためにまず、あなたがそう

<xsl:key name="parent" match="a" use="@myattr" /> 

その後のようなキーを定義し、子供のために、あなたはどこの子IDがよい場合には(アカウントに親IDと子IDの両方を取る必要があります異なる親のIDを持っているし、そうだろう異なるグループ)次に

<xsl:key name="child" match="b" use="concat(../@myattr, '|', @myattr)" /> 

、個別の親のIDを取得するには、あなたがこれを行う....

<xsl:apply-templates select="a[generate-id() = generate-id(key('parent', @myattr)[1])]" /> 

した別個の親の中に、これを行う、個別の子要素を取得するには...

<xsl:apply-templates select="key('parent', @myattr)/b 
           [generate-id() = generate-id(key('child', concat(../@myattr, '|', @myattr))[1])]" /> 

このXSLTを試してみてください

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" indent="yes" /> 

    <xsl:key name="parent" match="a" use="@myattr" /> 
    <xsl:key name="child" match="b" use="concat(../@myattr, '|', @myattr)" /> 

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

    <xsl:template match="myxml"> 
    <xsl:copy> 
     <xsl:apply-templates select="a[generate-id() = generate-id(key('parent', @myattr)[1])]" /> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="a"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*" /> 
     <xsl:apply-templates select="key('parent', @myattr)/b[generate-id() = generate-id(key('child', concat(../@myattr, '|', @myattr))[1])]" /> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="b"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*" /> 
     <xsl:apply-templates select="key('child', concat(../@myattr, '|', @myattr))/c" /> 
    </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 
+0

これは私が必要とするものです。確かに多くのありがとう! – Squidx3