输入文件:
<myroot>
<nodeA id="a">
<section id="i">
<item id="0" method="a"> <!-- parent section id="i" , keep this node-->
<somechild>a</somechild>
</item>
<item id="1" method="a">
<otherchild>a</otherchild>
</item>
</section>
<cell id="i">
<part id="1" method="b"> <!-- parent cell id="i", keep this node-->
<attr>u</attr>
</part>
</cell>
<section id="i">
<item id="0" method="a"> <!-- parent section id="i", remove this node-->
<type>blah</type>
</item>
<item id="3" method="a">
<other>xx</other>
</item>
<item id="0" method="b"> <!-- this has same id but different method, so we keep this -->
<otherchild>a</otherchild>
</item>
</section>
<cell id="i">
<part id="1" method="b"> <!-- parent cell id="i", remove this node -->
<attr>y</attr>
</part>
</cell>
</nodeA>
<nodeA id="b">
<section id="i">
<item id="1" method="a">
<otherchild>a</otherchild>
</item>
</section>
<section id="i">
<item id="0" method="a">
<type>blah</type>
</item>
<item id="1" method="a">
<other>xx</other>
</item>
</section>
</nodeA>
<nodeB id="a">
<cell id="i">
<part id="1" method="b">
<attr>u</attr>
</part>
</cell>
<section id="i">
<item id="0" method="a">
<type>blah</type>
</item>
</section>
<cell id="i">
<part id="1" method="b">
<attr>y</attr>
</part>
</cell>
</nodeB>
</myroot>
输出:
<myroot>
<nodeA id="a">
<section id="i">
<item id="0" method="a">
<somechild>a</somechild>
</item>
<item id="1" method="a">
<otherchild>a</otherchild>
</item>
</section>
<cell id="i">
<part id="1" method="b">
<attr>u</attr>
</part>
</cell>
<section id="i">
<item id="3" method="a">
<other>xx</other>
</item>
<item id="0" method="b"> <!-- this has same id but different method, so we keep this -->
<otherchild>a</otherchild>
</item>
</section>
</nodeA>
<nodeA id="b">
<section id="i">
<item id="1" method="a">
<otherchild>a</otherchild>
</item>
</section>
<section id="i">
<item id="0" method="a">
<type>blah</type>
</item>
</section>
</nodeA>
<nodeB id="a">
<cell id="i">
<part id="1" method="b">
<attr>u</attr>
</part>
</cell>
<section id="i">
<item id="0" method="a">
<type>blah</type>
</item>
</section>
</nodeB>
</myroot>
任何人都可以帮助我进行转换,这样如果一个节点出现两次或更多次且具有相同的父ID,我们只保留第一次出现并忽略其他节点。
此外,文件中还有另一个元素<nodeB></nodeB>
,<nodeC></nodeC>
。等等
非常感谢。
约翰
答案 0 :(得分:1)
我认为您需要定义一个键来“复制”重复项。它们似乎根据节点名称,@ id和@method属性以及父节点和@id进行分组。因此,您可以像这样定义键:
<xsl:key
name="duplicates"
match="*"
use="concat(local-name(), '|', @id, '|', @method, '|', local-name(..), '|', ../@id, '|', local-name(../..), '|', ../../@id)"/>
然后,您需要忽略键中不是第一个的元素。我认为你还需要一个子句来匹配作为'子'元素的元素(否则将忽略哪些节元素)
<xsl:template
match="*
[@id!='']
[not(.//*[@id!=''])]
[generate-id() != generate-id(key('duplicates', concat(local-name(), '|', @id, '|', @method, '|', local-name(..), '|', ../@id, '|', local-name(../..), '|', ../../@id))[1])]/>
为了增加复杂性,看起来你不想输出所有子元素都是重复的元素。
<xsl:template
match="*
[@id!='']
[.//*[@id!='']]
[not(.//*
[not(.//*[@id!=''])]
[generate-id() = generate-id(key('duplicates', concat(local-name(), '|', @id, '|', @method, '|', local-name(..), '|', ../@id, '|', local-name(../..), '|', ../../@id))[1])])
]" />
尝试以下XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="duplicates" match="*" use="concat(local-name(), '|', @id, '|', @method, '|', local-name(..), '|', ../@id, '|', local-name(../..), '|', ../../@id)"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[@id!=''][not(.//*[@id!=''])][generate-id() != generate-id(key('duplicates', concat(local-name(), '|', @id, '|', @method, '|', local-name(..), '|', ../@id, '|', local-name(../..), '|', ../../@id))[1])]"/>
<xsl:template match="*[@id!=''][.//*[@id!='']][not(.//*[not(.//*[@id!=''])][generate-id() = generate-id(key('duplicates', concat(local-name(), '|', @id, '|', @method, '|', local-name(..), '|', ../@id, '|', local-name(../..), '|', ../../@id))[1])])]"/>
</xsl:stylesheet>
当应用于您的示例XML时,输出以下内容:
<myroot>
<nodeA id="a">
<section id="i">
<item id="0" method="a"><!-- parent section id="i" , keep this node-->
<somechild>a</somechild>
</item>
<item id="1" method="a">
<otherchild>a</otherchild>
</item>
</section>
<cell id="i">
<part id="1" method="b"><!-- parent cell id="i", keep this node-->
<attr>u</attr>
</part>
</cell>
<section id="i">
<item id="3" method="a">
<other>xx</other>
</item>
<item id="0" method="b"><!-- this has same id but different method, so we keep this -->
<otherchild>a</otherchild>
</item>
</section>
</nodeA>
<nodeA id="b">
<section id="i">
<item id="1" method="a">
<otherchild>a</otherchild>
</item>
</section>
<section id="i">
<item id="0" method="a">
<type>blah</type>
</item>
</section>
</nodeA>
<nodeB id="a">
<cell id="i">
<part id="1" method="b">
<attr>u</attr>
</part>
</cell>
<section id="i">
<item id="0" method="a">
<type>blah</type>
</item>
</section>
</nodeB>
</myroot>