Как заставить это XSL-преобразование учитывать только для братьев и сестер с одинаковым идентификатором?

У меня есть этот XSLT 2.0:

<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-sibling::*[name()=current()/name()]
                       [@id = current()/@id]
                       [../../@id = current()/../../@id][1])]" />
</xsl:stylesheet>

Таким образом, любой последующий дубликат (с тем же именем, идентификатором, методом и потомками) будет удален доreset (рассматривается как уникальный или первый раз, когда он обнаружен)

The reset will happen if node with the same and id has different method.

Чтобы сделать это более понятным, у меня есть этот упрощенный пример в качестве иллюстрации:

<elem id="1" method="a" />
   <elem id="1" method="a" /> <!-- 1. this is duplicate -->
   <elem id="1" method="b" /> <!-- 2. this elem id=1 has different method, so it will be the reset point for elem id=1 -->
   <elem id="1" method="a" /> <!-- 3. this will be treated as unique because it's reset now so we don't remove this-->
   <elem id="2" method="a" /> <!--4.-->
   <elem id="1" method="a" /> <!-- this is repetitive for 3 and it willl be removed -->
   <elem id="2" method="a" /> <!-- this is repetitive for 4 so we remove this-->
and will be removed -->

After transformation it will be simplified into:

   <elem id="1" method="a" />
   <elem id="1" method="b" />
   <elem id="1" method="a" /> <!-- 3. this will be treated as unique because it's reset now so we don't remove this-->
   <elem id="2" method="a" />

Так что, если он применяется к моему 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"> <!-- this will be the reset point -->
                    <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"> <!-- this will be the reset point -->
                    <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>

Также, если два сравниваемых узла не разделяют одну и ту же «gridA» Уровень узла, то они не должны рассматриваться как дубликаты для удаления.

Я также собираюсь использовать

<xsl:value-of select="count($this-node/(preceding-sibling::* | ../preceding-sibling::*[@id = $this-node/parent::*/@id]/*)[name() = $this-node/name()][@id = $this-node/@id][deep-equal(*, $this-node/*)][@method = $this-node/@method]) mod 2 = 1"/>

как мой алгоритм сброса, но первое решение лучше просто настроить его для работы с братьями и сестрами с тем же идентификатором. (из примера это:<blockA id="xx">) или если у кого-то есть лучшие решения, я бы очень хотел знать.

Я надеюсь, что кто-нибудь может просветить меня по этой проблеме, так как это очень трудно для меня понять.

Большое спасибо и прошу прощения за длинные вопросы.

Ответы на вопрос(1)

Ваш ответ на вопрос