0

输入文件:

    <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>. 等等。非常感谢。约翰

4

1 回答 1

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>
于 2012-05-16T09:02:49.047 回答