2

同じ親から連続した重複ノードを削除したいと思います。これにはまったく同じ子もあります。

入力シナリオ 1:

<myroot>
    <nodeA id="a">
        <section id="i">  
            <item1 id="0" method="create"> 
                <somechild>a</somechild>
            </item1>

            <item1 id="1" method="create">
                <otherchild>a</otherchild>
            </item1>
        </section>        

        <section id="i">
            <item1 id="0" method="create"> <!-- second consecutive create, we remove this -->
                <somechild>a</somechild>
            </item1>
            <item1 id="0" method="create"> <!-- third consecutive create, but children have different value , so we don't remove this -->
                <somechild>bbb</somechild>
            </item1>
            <item1 id="3" method="create">
                <other>xx</other>    
            </item1>

            <item1 id="0" method="change"> 
                <otherchild>a</otherchild>
            </item1>
        </section>
    </nodeA>

    <nodeA id="b">
        <section id="i">  
            <item1 id="0" method="create"> 
                <somechild>a</somechild>
            </item1>

            <item1 id="1" method="create">
                <otherchild>a</otherchild>
            </item1>
        </section>        

        <section id="i">
            <item1 id="0" method="create"> <!-- second consecutive create, we remove this -->
                <somechild>a</somechild>
            </item1>
            <item1 id="0" method="create"> <!-- third consecutive create, but children have different value , so we don't remove this -->
                <somechild>bbb</somechild>
            </item1>
            <item1 id="3" method="create">
                <other>xx</other>    
            </item1>

            <item1 id="0" method="change"> 
                <otherchild>a</otherchild>
            </item1>
        </section>
    </nodeA>

    <nodeB id="b">
        <section id="i">  
            <item1 id="0" method="create"> 
                <somechild>a</somechild>
            </item1>

            <item1 id="1" method="create">
                <otherchild>a</otherchild>
            </item1>
        </section>        

        <section id="i">
            <item1 id="0" method="create"> <!-- second consecutive create, we remove this -->
                <somechild>a</somechild>
            </item1>
            <item1 id="0" method="create"> <!-- third consecutive create, but children have different value , so we don't remove this -->
                <somechild>bbb</somechild>
            </item1>
            <item1 id="3" method="create">
                <other>xx</other>    
            </item1>

            <item1 id="0" method="change"> 
                <otherchild>a</otherchild>
            </item1>
        </section>
    </nodeB>
</myroot>

私の結果:

<myroot>
    <nodeA id="a">
        <section id="i">
            <item1 id="0" method="create">
                <somechild>a</somechild>
            </item1>
            <item1 id="1" method="create">
                <otherchild>a</otherchild>
            </item1>
        </section>
        <section id="i">
            <item1 id="0" method="create">
                <somechild>bbb</somechild>
            </item1>
            <item1 id="3" method="create">
                <other>xx</other>
            </item1>
            <item1 id="0" method="change">
                <otherchild>a</otherchild>
            </item1>
        </section>
    </nodeA>
    <nodeA id="b">
        <section id="i"/>
        <section id="i"/>
    </nodeA>
    <nodeB id="b">
        <section id="i"/>
        <section id="i"/>
    </nodeB>
</myroot>

期待される出力:

<myroot>
    <nodeA id="a">
        <section id="i">  
            <item1 id="0" method="create"> 
                <somechild>a</somechild>
            </item1>

            <item1 id="1" method="create">
                <otherchild>a</otherchild>
            </item1>
        </section>        

        <section id="i">
            <item1 id="0" method="create"> 
                <somechild>bbb</somechild>
            </item1>
            <item1 id="3" method="create">
                <other>xx</other>    
            </item1>

            <item1 id="0" method="change"> 
                <otherchild>a</otherchild>
            </item1>
        </section>
    </nodeA>

    <nodeA id="b">
        <section id="i">  
            <item1 id="0" method="create"> 
                <somechild>a</somechild>
            </item1>

            <item1 id="1" method="create">
                <otherchild>a</otherchild>
            </item1>
        </section>        

        <section id="i">
            <item1 id="0" method="create"> 
                <somechild>bbb</somechild>
            </item1>
            <item1 id="3" method="create">
                <other>xx</other>    
            </item1>

            <item1 id="0" method="change"> 
                <otherchild>a</otherchild>
            </item1>
        </section>
    </nodeA>

    <nodeB id="b">
        <section id="i">  
            <item1 id="0" method="create"> 
                <somechild>a</somechild>
            </item1>

            <item1 id="1" method="create">
                <otherchild>a</otherchild>
            </item1>
        </section>        

        <section id="i">
            <item1 id="0" method="create"> 
                <somechild>bbb</somechild>
            </item1>
            <item1 id="3" method="create">
                <other>xx</other>    
            </item1>

            <item1 id="0" method="change"> 
                <otherchild>a</otherchild>
            </item1>
        </section>
    </nodeB>
</myroot>

上記の最初のシナリオでは、2 番目の連続する create のみが同じ子を持ち、3 番目の連続createするメソッドは異なる子を持つため、2 番目のメソッドのみを削除します。

2 番目の入力シナリオ (より多くのバリエーション):

<myroot>
    <nodeB id="a">
        <cell id="i">              
            <item2 id="1" method="create">
                <otherchild>a</otherchild>
            </item2>

            <item2 id="0" method="create"> 
                <otherchild>a</otherchild>
            </item2>

            <item2 id="1" method="modify">
                <otherchild>a</otherchild>
            </item2>        
        </cell>        

        <cell id="i">
            <item2 id="1" method="modify"> <!-- second consecutive modify, we remove this -->
                <otherchild>a</otherchild>
            </item2>

            <item2 id="1" method="modify"> <!-- third consecutive modify, BUT different chldren, we do NOT remove this -->
                <otherchild>a</otherchild>
                <somechild>aa</somechild>
            </item2>

            <item2 id="1" method="delete" /> 

            <item2 id="0" method="create"> 
                <somechild>bbb</somechild>
            </item2>

            <item2 id="1" method="delete" /> <!-- second consecutive delete, we remove this -->

            <item2 id="3" method="create">
                <other>xx</other>    
            </item2>

            <item2 id="1" method="delete" />  <!-- third consecutive delete, we remove this -->           
        </cell>
    </nodeB>
</myroot>

出力:

<myroot>
    <nodeB id="a">
        <cell id="i">              
            <item2 id="1" method="create">
                <otherchild>a</otherchild>
            </item2>

             <item2 id="0" method="create"> 
                <otherchild>a</otherchild>
            </item2>

            <item2 id="1" method="modify">
                <otherchild>a</otherchild>
            </item2>        
        </cell>        

        <cell id="i">
            <item2 id="1" method="modify">
                <otherchild>a</otherchild>
                <somechild>aa</somechild>
            </item2>

            <item2 id="1" method="delete" /> 

            <item2 id="0" method="create"> 
                <somechild>bbb</somechild>
            </item2>           
        </cell>
    </nodeB>
</myroot>

これに取り組んでいません:

    <myroot>     
        <node1 id="a">
            <section id="i">
                <item1 id="0" method="start">
                    <somechild>a</somechild>
                </item1>
                <item1 id="0" method="start"> <!-- this one is successive from the previous so we eliminate -->
                    <somechild>a</somechild>
                </item1>
                <item1 id="0" method="stop"/>                
                <item1 id="0" method="start"> <!-- this will be treated as new starting point -->
                    <somechild>a</somechild>
                </item1>
            </section>  

            <section id="i">
                <item1 id="0" method="start"> <!-- this one is successive from the previous so we eliminate -->
                    <somechild>a</somechild>
                </item1>
            </section>                
        </node1>
    </myroot>

output:

    <myroot>     
        <node1 id="a">
            <section id="i">
                <item1 id="0" method="start">
                    <somechild>a</somechild>
                </item1>
                <item1 id="0" method="start"> <!-- this one is successive from the previous so we eliminate -->
                    <somechild>a</somechild>
                </item1>
                <item1 id="0" method="stop"/>                          
            </section>                  
            <section id="i"/>                              
        </node1>
    </myroot>

The correct output should be:

    <myroot>     
        <node1 id="a">
            <section id="i">
                <item1 id="0" method="start">
                    <somechild>a</somechild>
                </item1>                   
                <item1 id="0" method="stop"/>                
                <item1 id="0" method="start"> <!-- this will be treated as new starting point -->
                    <somechild>a</somechild>
                </item1>
            </section>                  
            <section id="i" />                   
        </node1>
    </myroot>

XSLT を使用してこのトリッキーな削除を手伝ってくれる人はいますか? どうもありがとう。

ジョン

4

1 に答える 1

5

XSLT 2.0のサンプルスタイルシートを次に示します。これは、その役割を果たしたり、少なくとも使用がどのようにdeep-equal役立つかを示したりする必要があります。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="2.0">

  <xsl:strip-space elements="*"/>
  <xsl:output indent="yes"/>

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

  <xsl:template match="/*/*/*/*[some $el in (preceding-sibling::* , preceding::*) satisfies deep-equal(., $el)]"/>

</xsl:stylesheet>

[編集]新しい要件では、それを解決する方法がわからないdeep-equalので、とを使用する新しいスタイルシートを作成しましfor-each-groupdeep-equal

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

  <xsl:strip-space elements="*"/>
  <xsl:output indent="yes"/>

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

  <xsl:template match="/*/*">
    <xsl:copy>
      <xsl:variable name="first-in-group" as="element()*">
        <xsl:for-each-group select="*" group-by="concat(node-name(.), '|', @id)">
          <xsl:for-each-group select="current-group()/*" group-by="concat(@id, '|', @method)">
            <xsl:sequence 
              select="for $pos in 1 to count(current-group())
                      return current-group()[$pos]
                              [every $item 
                              in subsequence(current-group(), 1, $pos - 1) 
                              satisfies not(deep-equal($item, current-group()[$pos]))] "/>
          </xsl:for-each-group>
        </xsl:for-each-group>
      </xsl:variable>
      <xsl:apply-templates select="@*"/>
      <xsl:apply-templates>
        <xsl:with-param name="first-in-group" select="$first-in-group" tunnel="yes"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="/*/*/*/*">
    <xsl:param name="first-in-group" tunnel="yes"/>
    <xsl:if test="$first-in-group intersect .">
      <xsl:call-template name="identity"/>
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>

そのスタイルシートでSaxon9.4をサンプルに適用すると、

<myroot>
    <nodeA id="a">
        <section id="i">  
            <item1 id="0" method="create"> 
                <somechild>a</somechild>
            </item1>

            <item1 id="1" method="create">
                <otherchild>a</otherchild>
            </item1>
        </section>        

        <section id="i">
            <item1 id="0" method="create"> <!-- second consecutive create, we remove this -->
                <somechild>a</somechild>
            </item1>
            <item1 id="0" method="create"> <!-- third consecutive create, but children have different value , so we don't remove this -->
                <somechild>bbb</somechild>
            </item1>
            <item1 id="3" method="create">
                <other>xx</other>    
            </item1>

            <item1 id="0" method="change"> 
                <otherchild>a</otherchild>
            </item1>
        </section>
    </nodeA>

    <nodeA id="b">
        <section id="i">  
            <item1 id="0" method="create"> 
                <somechild>a</somechild>
            </item1>

            <item1 id="1" method="create">
                <otherchild>a</otherchild>
            </item1>
        </section>        

        <section id="i">
            <item1 id="0" method="create"> <!-- second consecutive create, we remove this -->
                <somechild>a</somechild>
            </item1>
            <item1 id="0" method="create"> <!-- third consecutive create, but children have different value , so we don't remove this -->
                <somechild>bbb</somechild>
            </item1>
            <item1 id="3" method="create">
                <other>xx</other>    
            </item1>

            <item1 id="0" method="change"> 
                <otherchild>a</otherchild>
            </item1>
        </section>
    </nodeA>

    <nodeB id="b">
        <section id="i">  
            <item1 id="0" method="create"> 
                <somechild>a</somechild>
            </item1>

            <item1 id="1" method="create">
                <otherchild>a</otherchild>
            </item1>
        </section>        

        <section id="i">
            <item1 id="0" method="create"> <!-- second consecutive create, we remove this -->
                <somechild>a</somechild>
            </item1>
            <item1 id="0" method="create"> <!-- third consecutive create, but children have different value , so we don't remove this -->
                <somechild>bbb</somechild>
            </item1>
            <item1 id="3" method="create">
                <other>xx</other>    
            </item1>

            <item1 id="0" method="change"> 
                <otherchild>a</otherchild>
            </item1>
        </section>
    </nodeB>
</myroot>

出力

<myroot>
   <nodeA id="a">
      <section id="i">
         <item1 id="0" method="create">
            <somechild>a</somechild>
         </item1>
         <item1 id="1" method="create">
            <otherchild>a</otherchild>
         </item1>
      </section>
      <section id="i">
         <item1 id="0" method="create"><!-- third consecutive create, but children have different value , so we don't re
move this --><somechild>bbb</somechild>
         </item1>
         <item1 id="3" method="create">
            <other>xx</other>
         </item1>
         <item1 id="0" method="change">
            <otherchild>a</otherchild>
         </item1>
      </section>
   </nodeA>
   <nodeA id="b">
      <section id="i">
         <item1 id="0" method="create">
            <somechild>a</somechild>
         </item1>
         <item1 id="1" method="create">
            <otherchild>a</otherchild>
         </item1>
      </section>
      <section id="i">
         <item1 id="0" method="create"><!-- third consecutive create, but children have different value , so we don't re
move this --><somechild>bbb</somechild>
         </item1>
         <item1 id="3" method="create">
            <other>xx</other>
         </item1>
         <item1 id="0" method="change">
            <otherchild>a</otherchild>
         </item1>
      </section>
   </nodeA>
   <nodeB id="b">
      <section id="i">
         <item1 id="0" method="create">
            <somechild>a</somechild>
         </item1>
         <item1 id="1" method="create">
            <otherchild>a</otherchild>
         </item1>
      </section>
      <section id="i">
         <item1 id="0" method="create"><!-- third consecutive create, but children have different value , so we don't re
move this --><somechild>bbb</somechild>
         </item1>
         <item1 id="3" method="create">
            <other>xx</other>
         </item1>
         <item1 id="0" method="change">
            <otherchild>a</otherchild>
         </item1>
      </section>
   </nodeB>
</myroot>

うまくいけば、あなたが削除したいすべてが削除され、あなたが保持したいすべてが保持されます。

于 2012-05-21T17:01:57.930 に答える