2

おおよそ次の構造を持つ XML があります。ここで関連する特性は、要素ペア "F" と "Child_Fs" の再帰的な関係です。「Child_Fs」には任意の数の「F」を含めることができ、「F」には「Child_Fs」を 1 つだけ含めることができます。

<A>
    <B>
        <F id="1">
            <J/>
            <K/>
            <Child_Fs>
                <F id="1.1">
                    <J/>
                    <K/>
                    <Child_Fs>
                        <F id="1.1.1">
                            <J/>
                            <K/>
                            <Child_Fs>
                                    ...
                            </Child_Fs>
                        </F>
                        <F id="1.1.2">
                            ...
                        </F>
                        <F id="1.1.3">
                            ...
                        </F>
                        <F id="1.1.4">
                            ...
                        </F>
                        .
                        .
                        .
                    </Child_Fs>
                </F>
                <F id="1.2">
                    ...
                </F>
                <F id="1.3">
                    ...
                </F>
                <F id="1.4">
                    ...
                </F>
                .
                .
                .
            </Child_Fs>
        </F>
        <F id="2">
            ...
        </F>
        <F id="3">
            ...
        </F>
        <F id="4">
            ...
        </F>
        .
        .
        .
        <G/>
        <H/>
        <I/>
    </B>
    <C/>
    <D/>
    <E/>
</A>

私の実際の XML には ID が含まれていません。説明のためにこの例に ID を書き込んだだけです。

したがって、変換後に取得したいのは次の XML です。ここで、すべての「F」要素は、対応する最上位の「F/Child_Fs」祖先の子です。F 要素の最大の深さは 2 つのオカレンス (F/Child_Fs/F/Childfs) のみにする必要があることを意味します。ここでのもう 1 つの重要な要件は、すべてのデータ (属性とテキストを含む) をそのまま維持することです。これは単なる再配置操作です。

<A>
    <B>
        <F id="1">
            <J/>
            <K/>
            <Child_Fs>
                <F id="1.1">
                    <J/>
                    <K/>
                    <Child_Fs>
                    </Child_Fs>
                </F>
                <F id="1.1.1">
                    <J/>
                    <K/>
                    <Child_Fs>
                    </Child_Fs>
                </F>
                ...
                <F id="1.1.2">
                    ...
                </F>
                <F id="1.1.3">
                    ...
                </F>
                <F id="1.1.4">
                    ...
                </F>
                .
                .
                .
                <F id="1.2">
                    ...
                </F>
                <F id="1.3">
                    ...
                </F>
                <F id="1.4">
                    ...
                </F>
                .
                .
                .
            </Child_Fs>
        </F>
        <F id="2">
            ...
        </F>
        <F id="3">
            ...
        </F>
        <F id="4">
            ...
        </F>
        .
        .
        .
        <G/>
        <H/>
        <I/>
    </B>
    <C/>
    <D/>
    <E/>
</A>

誰かが私にこれについてのヒントを与えることができれば、とても感謝しています。今まで、正しい XSL スタイルシートを思いつくことができませんでした。

よろしくお願いします。

4

2 に答える 2

0

この変換:

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

 <xsl:template match="Child_Fs[ancestor::Child_Fs]">
   <xsl:apply-templates/>
 </xsl:template>
</xsl:stylesheet>

提供された XML ドキュメントに適用した場合:

<A>
    <B>
        <F id="1">
            <J/>
            <K/>
            <Child_Fs>
                <F id="1.1">
                    <J/>
                    <K/>
                    <Child_Fs>
                        <F id="1.1.1">
                            <J/>
                            <K/>
                            <Child_Fs>
                                    ...
                            </Child_Fs>
                        </F>
                        <F id="1.1.2">
                            ...
                        </F>
                        <F id="1.1.3">
                            ...
                        </F>
                        <F id="1.1.4">
                            ...
                        </F>
                        .
                        .
                        .
                    </Child_Fs>
                </F>
                <F id="1.2">
                    ...
                </F>
                <F id="1.3">
                    ...
                </F>
                <F id="1.4">
                    ...
                </F>
                .
                .
                .
            </Child_Fs>
        </F>
        <F id="2">
            ...
        </F>
        <F id="3">
            ...
        </F>
        <F id="4">
            ...
        </F>
        .
        .
        .
        <G/>
        <H/>
        <I/>
    </B>
    <C/>
    <D/>
    <E/>
</A>

必要な正しい結果が生成されます。

<A>
   <B>
      <F id="1">
         <J/>
         <K/>
         <Child_Fs>
            <F id="1.1">
               <J/>
               <K/>
               <F id="1.1.1">
                  <J/>
                  <K/>
                                        ...
                                </F>
               <F id="1.1.2">
                                ...
                            </F>
               <F id="1.1.3">
                                ...
                            </F>
               <F id="1.1.4">
                                ...
                            </F>
                            .
                            .
                            .
                        </F>
            <F id="1.2">
                        ...
                    </F>
            <F id="1.3">
                        ...
                    </F>
            <F id="1.4">
                        ...
                    </F>
                    .
                    .
                    .
                </Child_Fs>
      </F>
      <F id="2">
                ...
            </F>
      <F id="3">
                ...
            </F>
      <F id="4">
                ...
            </F>
            .
            .
            .
            <G/>
      <H/>
      <I/>
   </B>
   <C/>
   <D/>
   <E/>
</A>

説明:

アイデンティティ ルールの適切な使用とオーバーライド。

于 2012-07-17T01:24:40.157 に答える
0

説明した構造が適切に保持されている限り、以下で説明するようにかなり単純なアルゴリズムを使用できます。構造がより自由な形になると、より難しい問題になります。

アルゴリズム

正確に 1 つの祖先 F を持つ Child_Fs:

  • これらは受信者です。それらはすべての子孫 F を取り込みます

複数の祖先 F を持つ Child_F:

  • これらはドナーです。他の子をコピーするが、F の子を除外する

d

<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:xi="http://www.w3.org/2001/XInclude"
      exclude-result-prefixes="xsl xi">
 <xsl:output method="xml" indent="yes"/>
 <xsl:strip-space elements="*" />
 
 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="Child_Fs[count(ancestor::F)=1]">
 <!-- Child_F which is recipient of all Fs. -->
 <xsl:copy>
  <xsl:apply-templates select="@* | node() | //F" />
 </xsl:copy>
</xsl:template> 

<xsl:template match="Child_Fs[count(ancestor::F) &gt; 1]">
 <!-- Child_F which is donor of Fs. -->
 <xsl:copy>
  <xsl:apply-templates select="@* | node()[not(self::F)]" />
 </xsl:copy>
</xsl:template>

</xsl:stylesheet> 
于 2012-07-17T01:35:20.410 に答える