この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メソッドにあります。
- それが最後のノードである場合は、前のすべてのノードを削除し、「停止」のあるノードを残します
- 'stop' メソッドを使用するノードが最後でない場合は、'stop' を使用してそのノードとその前のすべてのノードを削除します (その停止後のすべてのノードを残します)。
これは、親の id 属性が同じである子の間で発生する必要があり、子ノードのみが削除されます (ユーザー ノードの削除後に空であっても、親は残ります)。
上記の例では:
- アイテム id=0 一時停止、アイテム id=0 停止 -> 結果はアイテム id=0 停止(親: アイテム id=a_1-一時停止) になります。
- 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 のみになります
- 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>
他のすべてのノードを解決するように変更できますか (ノードと親の名前は何でもかまいません)。どうもありがとう。
敬具、ジョン