この入力 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 つのノードが次々に出現し、同じname
andを持つ場合、繰り返しid
と見なされます。method
children
例えば:
<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 を使用してこのような変換を実現する方法を教えてください。助けてくれてどうもありがとう。
ジョン