带有node()的xpath,如何表达`node()[.// x]`condition?

时间:2013-11-19 19:03:21

标签: xpath

我有一个必须匹配文字和标签的XPath,标签<aa>除外;所以,

./node()[name()!='aa']

是正确的xpath。 但是对于标签aa进入节点的情况,这是不够的,我需要类似的东西,

./node()[name()!='aa' and not(.//aa)]

但是此xpath 不起作用(!)


我用过 ./*[not(self::aa or .//aa)] | ./text() 但是它丢失了节点的原始序列顺序。使用XSLT时,这个问题更加明显,例如:

     <xsl:for-each select="./*[not(self::aa or .//aa)] | ./text()">
            <xsl:copy-of select="."/>
     <xsl:for-each>

无法按预期工作(无法确保节点的顺序)。使用./node()时,订单始终是正确的。

PS:使用XSLT我们有一个解决方案,使用所有解释的xpath,

 <xsl:for-each select="./node()[name()!='aa']">
        <xsl:if test="not(.//aa)"><xsl:copy-of select="."/><xsl:if>
 <xsl:for-each>

但理想/最简单的不能使用相同的结果(处理大型和复杂的输入时),

            <xsl:copy-of select="*[not(self::aa or .//aa)] | ./text()"/>

1 个答案:

答案 0 :(得分:1)

我想象你的文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <aa/>
  <b>
    <aa/>
  </b>
  <c>
    <b>
      <aa/>
    </b>
  </c>
  <d/>
  <e>
    <b/>
  </e>
</root>

然后是表达式

//node()[not(descendant-or-self::aa)]

返回所有节点(包括空白文本节点),这些节点本身不是<aa>元素或具有<aa>后代。 <aa>的孩子也匹配。

您可能想要做类似

的事情
<xsl:copy-of select="node()[not(descendant-or-self::aa)]"/>
相关问题