如果我有这个 xml 文件:
<root>
<node id="a">
<section id="a_1">
<item id="0">
<attribute>
<color>Red</color>
</attribute>
</item>
</section>
<section id="a_2">
<item id="0">
<attribute>
<color>Red</color>
</attribute>
</item>
</section>
</node>
<node id="b">
<section id="b_1">
<user id="b_1a">
<attribute>
<name>John</name>
</attribute>
</user>
<user id="b_1b">
<attribute>a</attribute>
</user>
</section>
<section id="b_1" method="create">
<user id="b_1a">
<attribute>
<name>John</name>
</attribute>
</user>
<user id="b_1c">
<attribute>a</attribute>
</user>
</section>
<section id="b_2">
<user id="b_1a">
<attribute>
<name>John</name>
</attribute>
</user>
</section>
</node>
</root>
我希望输出是这样的:
<root>
<node id="a">
<section id="a_1">
<item id="0">
<attribute>
<color>Red</color>
</attribute>
</item>
</section>
<section id="a_2">
<item id="0">
<attribute>
<color>Red</color>
</attribute>
</item>
</section>
</node>
<node id="b">
<section id="b_1">
<user id="b_1a">
<attribute>
<name>John</name>
</attribute>
</user>
<user id="b_1b">
<attribute>a</attribute>
</user>
</section>
<section id="b_1" method="create">
<user id="b_1c">
<attribute>a</attribute>
</user>
</section>
<section id="b_2">
<user id="b_1a">
<attribute>
<name>John</name>
</attribute>
</user>
</section>
</node>
</root>
正如我们所看到的,只要 id 相同,它就会被视为一个部分 id,即使它上面有其他方法。因此,我们在包含"方法创建"的第二部分 id (b_1) 中删除用户 id (b_1a)。这真的让我感到沮丧,我无法省略该方法。因此,任何帮助将不胜感激。如果我们看一下部分 ID b_2它也具有相同的用户 ID b_1和相同的"John",但我们没有删除它,因为它位于不同的部分 ID 中。所以基本上我们根据部分 id 来比较它。
PS:元素可以是任何并不总是用户或部分,但只要id相同。
非常感谢。
亲切问候John
虽然我不完全清楚要求,但我认为您可能希望按元素的 id 和包含的部分 id 对元素进行分组。这意味着您可以使用 xsl:key 来查找元素
<xsl:key
name="lookup"
match="section//*[@id]" use="concat(ancestor::section[1]/@id, '|', @id)" />
在这里,我们根据元素的部分 ID 和自己的 ID 查找元素(任何元素)。然后,这只是在查找中存在另一个具有匹配 id 的元素的部分中忽略元素的情况。
<xsl:template
match="section//*[@id]
[generate-id()
!= generate-id(key('lookup', concat(ancestor::section[1]/@id, '|', @id))[1])]" />
(这实际上是在说,这个元素是查找中的第一个元素吗?如果没有,请忽略它)
这是完整的 XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="lookup" match="section//*[@id]" use="concat(ancestor::section[1]/@id, '|', @id)" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="section//*[@id][generate-id() != generate-id(key('lookup', concat(ancestor::section[1]/@id, '|', @id))[1])]" />
</xsl:stylesheet>
应用于示例 XML 时,输出如下
<root>
<node id="a">
<section id="a_1">
<item id="0">
<attribute>
<color>Red</color>
</attribute>
</item>
</section>
<section id="a_2">
<item id="0">
<attribute>
<color>Red</color>
</attribute>
</item>
</section>
</node>
<node id="b">
<section id="b_1">
<user id="b_1a">
<attribute>
<name>John</name>
</attribute>
</user>
<user id="b_1b">
<attribute>a</attribute>
</user>
</section>
<section id="b_1" method="create">
<user id="b_1c">
<attribute>a</attribute>
</user>
</section>
<section id="b_2">
<user id="b_1a">
<attribute>
<name>John</name>
</attribute>
</user>
</section>
</node>
</root>