Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml Xpath:包含某些节点并排除其他节点的复杂表达式_Xml_Xslt_Xpath - Fatal编程技术网

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

Xml Xpath:包含某些节点并排除其他节点的复杂表达式,xml,xslt,xpath,Xml,Xslt,Xpath,xml示例: <foo> <bar name="bar1"> </bar> <bar name="bar2"> </bar> </foo> <qux> <foo> <bar name="bar3"> </bar> </foo> <bar name="bar4">

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)的子元素而不是嵌套foo(bar3)的所有bar元素的表达式是什么


提前谢谢你

正如@Cheeso所说,该文件无效,而且似乎与您的问题不符

如果这是您所指的文档(其中
qux
位于第一个
foo

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

选择作为其子级的所有条形图元素的表达式是什么 根foo(bar1、bar2、bar4)而不是嵌套foo(bar3)

这里可能是最简单和最短的XPath表达式之一当对任何格式良好的XML文档进行计算时,如果该文档具有顶部元素
foo
,并且可能具有任何级别的嵌套
foo
元素,则会精确选择其唯一的
foo
祖先是顶部元素的
bar
元素:

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

基于XSLT的验证

<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>
<bar name="bar1">

</bar>
<bar name="bar2">

</bar>
<bar name="bar4">

</bar>
<bar name="bar6">

</bar>
此转换

<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>
<bar name="bar1">

</bar>
<bar name="bar2">

</bar>
<bar name="bar4">

</bar>
<bar name="bar6">

</bar>

应用于以下XML文档时(基于提供的XML片段,但要使其成为格式良好的XML文档,并增加稍微多一些嵌套/复杂性,以使其有趣):


准确输出所需元素

<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>
<bar name="bar1">

</bar>
<bar name="bar2">

</bar>
<bar name="bar4">

</bar>
<bar name="bar6">

</bar>


这不是合法的XML文档。有多个根元素。bar4不是根foo的子元素。@Michael Kay-你说得对,根foo也应该包含qux元素。请看我对第一个答案的第一个回答。@MichaelKay:我的解释是OP的意思是“后代”——而不是“孩子”——谢谢你的回答!关于xml,您是对的。需求是-可以有多层嵌套的foo和bar元素。选择作为当前foo而不是任何其他foo的后代的所有条形图元素。再次感谢@用户897210,好吧,更具体一点。我用两种可能的解决方案更新了答案。取决于您发现什么更具可读性。+1表示更好的表达式。我就知道我迟早会在这里见到你!