我有这个输入 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)。
我需要删除一个被认为是重复的节点。
具有相同的两个节点,如果一个接一个出现并且具有相同的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
hasdifferent 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 实现这种转换。非常感谢您的帮助。
约翰