1

このxmlファイルがある場合:

    <root> 
    <node id="a">
        <Items id="a_1" method="pause">
            <item id="0" method="pause">
                <attribute>
                    <color>Red</color>
                </attribute>
            </item>
        </Items>

        <Items id="a_1" method="pause">
            <item id="0" method="stop">
                <attribute>
                    <color>Red</color>
                </attribute>
            </item>
        </Items>            
    </node>

    <node id="b">
        <Persons id="b_1">    
            <person id="b_1b" method="pause">
                <attribute>a</attribute>
            </person>       
            <person id="b_1a" method="start">
                <attribute>
                    <name>John</name>
                </attribute>
            </person>
            <person id="b_1b" method="stop">
                <attribute>a</attribute>
            </person>
            <person id="b_1a" method="pause">
                <attribute>a</attribute>
            </person>
        </Persons>

        <Persons id="b_1" method="start">               
            <person id="b_1a" method="stop">
                <attribute>a</attribute>
            </person>

            <person id="b_1b" method="start">
                <attribute>a</attribute>
            </person>
            <person id="b_1b" method="pause">
                <attribute>a</attribute>
            </person>
        </Persons>

        <Persons id="b_2">                
            <person id="b_1a" method="start">
                <attribute>
                    <name>John</name>
                </attribute>
            </person>
        </Persons>
    </node>
</root>

期待される出力は次のとおりです。

    <root> 
    <node id="a">
        <Items id="a_1" method="pause">

        </Items>

        <Items id="a_1" method="pause">
            <item id="0" method="stop">
                <attribute>
                    <color>Red</color>
                </attribute>
            </item>
        </Items>            
    </node>

    <node id="b">
        <Persons id="b_1">    
        </Persons>

        <Persons id="b_1" method="start">               
            <person id="b_1a" method="stop">
                <attribute>a</attribute>
            </person>

            <person id="b_1b" method="start">
                <attribute>a</attribute>
            </person>
            <person id="b_1b" method="pause">
                <attribute>a</attribute>
            </person>
        </Persons>

        <Persons id="b_2">                
            <person id="b_1a" method="start">
                <attribute>
                    <name>John</name>
                </attribute>
            </person>
        </Persons>
    </node>
</root>

アルゴリズムの鍵はstopメソッドにあります。

  1. それが最後のノードである場合は、前のすべてのノードを削除し、「停止」のあるノードを残します
  2. 'stop' メソッドを使用するノードが最後でない場合は、'stop' を使用してそのノードとその前のすべてのノードを削除します (その停止後のすべてのノードを残します)。

これは、親の id 属性が同じである子の間で発生する必要があり、子ノードのみが削除されます (ユーザー ノードの削除後に空であっても、親は残ります)。

上記の例では:

  1. アイテム id=0 一時停止、アイテム id=0 停止 -> 結果はアイテム id=0 停止(親: アイテム id=a_1-一時停止) になります。
  2. person id=b_1a start then person id=b_1a pause then person id=b1_a stop (parents: Person id=b_1) - 結果は person id=b_1a stop のみになります
  3. person id=b_1b 一時停止してから person id=b_1b 停止してから person id=b_1b 開始してから person id=b_1b 一時停止 -> person id=b_1b 開始してから person id=b_1b 一時停止になります (ここでも、親の Person id の下にあるすべての人物を比較します=b_1; 親では、例に示されているのと同じ id である限り、そのうちの 1 つにメソッドがなくてもかまいません)

これは、「人」ノードについてのみ得たものです。

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

   <!-- Ignore person with 'stop' method which are not the last such person -->
   <xsl:template match="person[@method='stop'][following::person[@method='stop']]"/>

   <!-- Match other persons -->
   <xsl:template match="person">
      <!-- Copy the person if there isn't a following person with the same id and 'stop' method -->
      <xsl:if test="not(following::person[@id=current()/@id][@method='stop'])">
         <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
         </xsl:copy>
      </xsl:if>
   </xsl:template>

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

他のすべてのノードを解決するように変更できますか (ノードと親の名前は何でもかまいません)。どうもありがとう。

敬具、ジョン

4

1 に答える 1

0

これは同じ親で発生する必要があります

これは、前述の制約が兄弟ノードにのみ適用されることを意味すると思います。しかし、id="0" を使用した例は、これが正しくないことを示しています。したがって、上記の句が理解できないと思います。

更新:これは、「1 つの親要素の子の間」ではなく、「親の id 属性が同じ値を持つ要素の間」を意味します。

これまでの仕様についての私の理解:

「停止」メソッドを持つ要素が最後に発生した場合、同じユーザー ID を持つ他のメソッド (「一時停止」や「実行」など) を持つ他のノードは削除されます。しかし、'stop' メソッドを持つ要素が最後でない場合、'stop' を持つ要素自体とその 'stop' より前のすべての要素 (同じ ID を持つ?) が削除されます。

これは次のように要約できるように私には思えます。

'stop' メソッドを持つ要素がある場合、その要素と、同じ要素名と同じ id 属性を持つ先行要素が削除されます。

この要約が正しくない場合は、明確にしてください。

他のすべてのノードを解決するように変更できますか (ノードと親の名前は何でもかまいません)。

テンプレート マッチングのみでこれを行う方法は考えていません。しかし、あなたがしたように xsl:if: で行うことができます:

<xsl:template match="*">
  <!-- Copy the element if there isn't a following sibling element with
       the same name, same id and 'stop' method, and if the element itself
       doesn't have a 'stop' method. -->
  <xsl:if test="not(@method = 'stop' or
                    following::*[local-name() = local-name(current()) and
                      @id = current()/@id and
                      ../@id = current()/../@id and
                      @method = 'stop'])">
     <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
     </xsl:copy>
  </xsl:if>
</xsl:template>

アルゴリズムの仕様を理解するのに少し苦労しているので、上記が望ましい結果をもたらさない場合は、その結果が望ましい結果と異なる具体的な例を挙げて、仕様を明確にしてください。

更新:最近のコメントに基づいて上記のコードを多少更新しましたが、今では理解したとおり、仕様と完全には一致していません。今夜はそれに取り組んでみます。(それ以外の方の撮影も大歓迎です!)

于 2012-04-24T14:23:19.813 に答える