-1

私の元の投稿Group/merge childs of same nodes in xml/xsltへの追加として、その構造が異なるノード (階層の上位ノード内) に対して複数回繰り返されるという問題に遭遇しました。

<Collection>
    <Questionnaire Name="Preferences" VersionID="3QW">
        <Subject ID="2355">
            <EventData Name="First Part">
                <FormData Name="Past">
                    <GroupData ID="xxx" Key="4" Temp="yyy">
                        <ItemData ID="zzz" Value="3"/>
                    </GroupData>
                    <GroupData ID="xxx" Key="4" Temp="yyy">
                        <ItemData ID="qqq" Value="4"/>
                    </GroupData>
                    ...
                </FormData>
                <FormData Name="Present">
                    <GroupData ID="yyy" Key="9" Temp="yyy">
                        <ItemData ID="www" Value="32"/>
                    </GroupData>
                    ...
                </FormData>             
            </EventData>
            <EventData Name="SecondPart">
                ...
            </EventData>
        </Subject>
        <Subject ID="9812">
            ...
        </Subject>
    </Questionnaire>    
</Collection>   

私が受け取った提案のバリエーションと他のいくつかのことを試した後、私は立ち往生しています。複数のレベル(および GroupData が子になる上位/祖父母ノードに分散されている)と関係があると思いますが、一意の ID がなくなっている可能性があります。では、各 GroupData ノードの子ノードを 1 つの GroupData ノードに取得するにはどうすればよいでしょうか (後者は常に存在するとは限らないため、ID と場合によっては Key で一致します)。注: 同じ GroupData ノード (対応する属性を持つ) を、各 FormData ノードの 1 つの GroupData ノードにマージする必要があります。

4

1 に答える 1

0

以下に、2 つの XSLT 1.0 ソリューションを示します。

1つの解決策は、最初の質問からDimiteの解決策を取り、キーを展開してFormDataを含めることです...

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="kGDByIdKey" match="FormData/GroupData"
  use="concat(@ID, '+', @Key, '+', generate-id(..))"/>

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

 <xsl:template match=
 "FormData/GroupData
    [generate-id()
    =
     generate-id(key('kGDByIdKey', concat(@ID, '+', @Key, '+', generate-id(..)))[1])
     ]">
    <xsl:copy>
      <xsl:apply-templates select=
       "@*|key('kGDByIdKey', concat(@ID, '+', @Key, '+', generate-id(..)))/node()"/>
    </xsl:copy>
 </xsl:template>

  <xsl:template match="GroupData"/>
</xsl:stylesheet>

別の解決策は、グループ化テストをテンプレート一致条件から、親 FormData 内の呼び出し xsl:apply-templates に移動します ...

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="kGDByIdKey" match="FormData/GroupData" use="concat(@ID, '+', @Key)" />

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

 <xsl:template match="FormData">
     <xsl:copy>
       <xsl:apply-templates select="
          @* |
          node()[not(self::GroupData)] |
          GroupData[generate-id() =
                    generate-id(key('kGDByIdKey', concat(@ID, '+', @Key))[1])]"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="FormData/GroupData">
     <xsl:copy>
       <xsl:apply-templates select="@*|
           key('kGDByIdKey', concat(@ID, '+', @Key))/node()"/>
     </xsl:copy>
 </xsl:template>
  <xsl:template match="GroupData"/>
</xsl:stylesheet>

どちらのスタイルシートも、GroupData の親が FormData のみであることを前提としています。FormData 親を持たない GroupData はすべて削除されます。

于 2012-08-15T15:12:23.367 に答える