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)。

我需要删除一个被认为是重复的节点。

具有相同的两个节点,如果一个接一个出现并且具有相同的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 idhasdifferent method的连续节点时,都会重置boundary下一次删除的。id

  • 我们需要考虑在一个父节点或兄弟节点(两个或多个具有相同元素名称和 id 的父节点)下的重复项,即(例如blockX:)
  • 如果被比较的两个节点不共享同一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