XSL选择所有节点,而不是另一个节点的节点

Har*_*OTA 1 xml xslt xpath

这是我的xml

<element1> <subel1/> </element1> <element2> <subel2/> </element2> <element3> <subel3/> </element3> <criteria> <subel3/> </criteria>
Run Code Online (Sandbox Code Playgroud)

我如何选择xsl不在标准子节点的所有节点?像这些

 <subel1/> <subel2/>
Run Code Online (Sandbox Code Playgroud)

这是怎么做到的?

如果xml格式为:

<element1> 
<el> subel1 </el>
</element1>
 <element2> 
<el> subel2 
</el> 
</element2> 
<element3> 
<el> subel3 </el> 
</element3> 
<criteria> 
<subel3/> 
</criteria>
Run Code Online (Sandbox Code Playgroud)

Dim*_*hev 6

这种转变:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
  <xsl:for-each select=
  "/*/*[not(self::criteria)]/*">
   <xsl:copy-of select=
   "self::node()[not(/*/criteria/*[name()=name(current())])]"/>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

当应用于此XML文档时(基于提供的XML片段,但将XML片段包含在顶部元素中并添加一个子节点criteria以使问题变得不那么简单):

<t>
    <element1>
        <subel1/>
    </element1>
    <element2>
        <subel2/>
    </element2>
    <element3>
        <subel3/>
    </element3>
    <criteria>
        <subel3/>
        <subel1/>
    </criteria>
</t>
Run Code Online (Sandbox Code Playgroud)

产生想要的结果(在编写时没有其他公布的答案产生正确的结果):

<subel2/>
Run Code Online (Sandbox Code Playgroud)

分步说明:

  1. XPath表达式:

    /*/*[not(self::criteria)]/*

选择其父元素是未命名元素"criteria"且元素是文档顶部元素的子元素.

  1. <xsl:for-each>指令中,我们检查当前节点的名称是否不是任何子节点的名称之一,criteria并且只复制这样的节点:

self::node()[not(/*/criteria/*[name()=name(current())])]

self::node()仅当不存在子节点时,此XPath表达式才会选择当前节点()/*/criteria,其名称与当前节点(not(/*/criteria/*[name()=name(current())]))的名称相同.

这里我们使用的事实not(someNode-Set)是,false()只有节点集someNode-Set为空.