使用xslt删除与XML相似的节点上的删除不完全相同

时间:2012-04-17 03:57:35

标签: xml xslt

如果我有这个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是相同的。

非常感谢。

亲切的问候, 约翰

1 个答案:

答案 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>