Xpath:复杂表达式包含一些节点并排除其他节点

时间:2011-09-20 01:14:36

标签: xml xslt xpath

示例xml:

<foo>
    <bar name="bar1">
    </bar>
    <bar name="bar2">
    </bar>
</foo>
<qux>
    <foo>
        <bar name="bar3">
        </bar>
    </foo>
     <bar name="bar4">
     </bar>
</qux>

选择所有作为根foo(bar1,bar2,bar4)的子元素的bar元素而不是嵌套foo(bar3)的表达式是什么?

提前谢谢!

2 个答案:

答案 0 :(得分:2)

  

选择所有子元素的表达式是什么?   根foo(bar1,bar2,bar4)但不是嵌套的foo(bar3)?

这可能是最简单和最短的XPath表达式之一,当在任何格式良好的XML文档上进行求值时,它具有顶级元素foo并且可能具有任何级别的嵌套{{ 1}}元素精确选择仅foo祖先是顶部元素的bar元素:

foo

此Xpath表达式选择文档中具有少于两个//bar[not(ancestor::foo[2])] 祖先的任何bar元素。因为根据定义,顶部元素是foo,这意味着每个foo都有这个顶级元素bar作为祖先。如果它位于嵌套foo内,则它至少具有第二个祖先foo,并且不会被上述XPath表达式选中,因为在这种情况下fooboolean(ancestor::foo[2])

基于XSLT的验证

此转化

true()

应用于以下XML文档(基于提供的XML片段,但使其成为格式良好的XML文档并添加更多嵌套/复杂性,以使其变得有趣):< / p>

<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:copy-of select=
   "//bar[not(ancestor::foo[2])]"/>
 </xsl:template>
</xsl:stylesheet>

完全输出所需元素

<foo>
    <bar name="bar1">
    </bar>
    <bar name="bar2">
    </bar>
    <qux>
        <foo>
           <baz>
             <bar name="bar3">
             </bar>
            </baz>
        </foo>
        <bar name="bar4">
        </bar>
        <qux>
            <foo>
                <bar name="bar5">
                </bar>
            </foo>
            <bar name="bar6">
            </bar>
        </qux>
    </qux>
</foo>

答案 1 :(得分:1)

正如@Cheeso所说,该文件无效,似乎没有问你的问题。

如果这是你想要的文件(qux在第一个foo内)

<foo>
    <bar name="bar1">
    </bar>
    <bar name="bar2">
    </bar>
    <qux>
        <foo>
            <bar name="bar3">
            </bar>
        </foo>
        <bar name="bar4">
        </bar>
    </qux>
</foo>

然后这里有两条路径

//bar[not(parent::foo[ancestor::foo])]
//bar[1 >= count(ancestor::foo)]

将选择您想要的元素(在.NET中测试)。