如果我有这个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是相同的。
非常感谢。
亲切的问候, 约翰答案 0 :(得分:1)
虽然我对要求并不完全清楚,但我认为您可能希望按 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>