2

重複の可能性:
この XSL 変換で同じ ID を持つ兄弟のみを考慮するにはどうすればよいですか?

この入力 XML があります。

<map>
    <region>
        <gridA id="1">
            <blockA id="01" method="build">                 
                <building1 id="x" method="build">
                    <otherchild>a</otherchild>
                </building1>
                <building1 id="x" method="build"> <!-- this one will be removed -->
                    <otherchild>a</otherchild>
                </building1>
            </blockA>    

            <blockA id="01">                 
                <building1 id="x" method="modify"> 
                    <otherchild>a</otherchild>
                </building1>
                <building1 id="x" method="build"> <!-- this one will be kept (prev node have same id but diff method so it's not considered as successive -->
                    <otherchild>a</otherchild>
                </building1>
            </blockA>    

            <blockA id="02">
                <building3 id="y" method="modify">
                    <otherchild>b</otherchild>
                </building3>
                <building2 id="x" method="demolish"/>
            </blockA>      

            <blockA id="01">                
                <building1 id="y" method="build"> <!-- this one will be kept (diff id) -->
                    <otherchild>a</otherchild>
                </building1>
                <building1 id="x" method="build"> <!-- this one will be removed -->
                    <otherchild>a</otherchild>
                </building1>
            </blockA>

            <blockA id="02">                
                <building3 id="y" method="modify"> <!-- this one will be removed -->
                    <otherchild>b</otherchild>
                </building3>
                <building2 id="x" method="demolish"/> <!-- this one will be removed -->
            </blockA>          
        </gridA>   

        <gridA id="2">
            <blockA id="01" method="build">                 
                <building1 id="x" method="build">
                    <otherchild>a</otherchild>
                </building1>
                <building1 id="x" method="build"> <!-- this one will be removed -->
                    <otherchild>a</otherchild>
                </building1>
                <building1 id="x" method="build"> <!-- this one will be kept (diff children) -->
                    <otherchild>b</otherchild>
                </building1>
            </blockA>                              
            <blockA id="01">                
                <building1 id="x" method="build"> <!-- this one will be removed -->
                    <otherchild>b</otherchild>
                </building1>
            </blockA> 
        </gridA>
        <gridB id="1">
            ...and so on..
        </gridB>
    </region>    
</map>

期待される出力:

<map>
    <region>
        <gridA id="1">
            <blockA id="01" method="build">                 
                <building1 id="x" method="build">
                    <otherchild>a</otherchild>
                </building1>
            </blockA>    

            <blockA id="01">                 
                <building1 id="x" method="modify"> 
                    <otherchild>a</otherchild>
                </building1>
                <building1 id="x" method="build"> <!-- this one will be kept (prev node have same id but diff method so it's not considered as successive -->
                    <otherchild>a</otherchild>
                </building1>
            </blockA>    

            <blockA id="02">
                <building3 id="y" method="modify">
                    <otherchild>b</otherchild>
                </building3>
                <building2 id="x" method="demolish"/>
            </blockA>      

            <blockA id="01">                
                <building1 id="y" method="build"> <!-- this one will be kept (diff id) -->
                    <otherchild>a</otherchild>
                </building1>
            </blockA>

            <blockA id="02"/>                         
        </gridA>   

        <gridA id="2">
            <blockA id="01" method="build">                 
                <building1 id="x" method="build">
                    <otherchild>a</otherchild>
                </building1>

                <building1 id="x" method="build"> <!-- this one will be kept (diff children) -->
                    <otherchild>b</otherchild>
                </building1>
            </blockA>                              
            <blockA id="01"/>  
        </gridA>
        <gridB id="1">
            ...and so on..
        </gridB>
    </region>    
</map>

これまでの XSLT:

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

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

    <xsl:template match="region/*/*/*
         [deep-equal(.,preceding::*[name()=current()/name()]
                       [@id = current()/@id]
                       [../../@id = current()/../../@id][1])]" />
</xsl:stylesheet>

現在の XSLT の問題は、兄弟で発生する重複 (つまり、同じ ID を持つ blockA) を区別できないことです。

反復的と見なされるノードを削除する必要があります。

同じ andを持つ 2 つのノードが次々に出現し、同じnameandを持つ場合、繰り返しidと見なされます。methodchildren

例えば:

<elem id="1" method="a" />
<elem id="1" method="a" /> <!-- this is repetitive for id=1-->
<elem id="1" method="b" /> 
<elem id="1" method="a" /> <!-- this is the new boundary for removal id=1-->
<elem id="2" method="a" /> 
<elem id="1" method="a" /> <!-- this is repetitive for id=1 -->
<elem id="2" method="a" /> <!-- this is repetitive for id=2 -->

次のように簡略化されます。

<elem id="1" method="a" />
<elem id="1" method="b" />
<elem id="1" method="a" /> <!-- this is the new boundary for removal id=1-->
<elem id="2" method="a" />

same id- hasを持つ連続するノードがあるたびに、different methodそのboundary次の削除のidがリセットされます。

  • 1 つの親または兄弟 (同じ要素名と ID を持つ 2 つ以上の親ノード) の下にある重複を考慮する必要があります。つまり (例: blockX)
  • 比較されている 2 つのノードが同じレベルを共有していない場合gridX、それらは削除される重複と見なされるべきではありません。
  • 後続の重複はすべて、重複しなくなるまで削除されます。例の最後の部分をコメント付きで参照してください。<!-- this is the new boundary for removal id=1-->ただし、前のノードが非重複ノードであるelem id=1 method=aため、削除されていません。elem id=1 method=b
  • したがって、キーは最初に同じ id を持つ連続するノードを調べてから、メソッドと子が同じかどうかを確認します。

申し訳ありませんが、これをよりわかりやすい文で説明する方法がわかりません。

説明が十分に明確で、混乱しないことを願っています。

XSLT を使用してこのような変換を実現する方法を教えてください。助けてくれてどうもありがとう。

ジョン

4

0 に答える 0