XPath:获取子节点包含属性的节点

假设我有以下XML:

<book category="CLASSICS"> <title lang="it">Purgatorio</title> <author>Dante Alighieri</author> <year>1308</year> <price>30.00</price> </book> <book category="CLASSICS"> <title lang="it">Inferno</title> <author>Dante Alighieri</author> <year>1308</year> <price>30.00</price> </book> <book category="CHILDREN"> <title lang="en">Harry Potter</title> <author>J K. Rowling</author> <year>2005</year> <price>29.99</price> </book> <book category="WEB"> <title lang="en">XQuery Kick Start</title> <author>James McGovern</author> <author>Per Bothner</author> <author>Kurt Cagle</author> <author>James Linn</author> <author>Vaidyanathan Nagarajan</author> <year>2003</year> <price>49.99</price> </book> <book category="WEB"> <title lang="en">Learning XML</title> <author>Erik T. Ray</author> <year>2003</year> <price>39.95</price> </book> 

我想做一个xpath,返回所有具有标题节点的书籍节点,其语言属性为“it”。

我的尝试看起来像这样:

//book[title[@lang='it']]

但是这没有用。 我期望找回节点:

 <book category="CLASSICS"> <title lang="it">Purgatorio</title> <author>Dante Alighieri</author> <year>1308</year> <price>30.00</price> </book> <book category="CLASSICS"> <title lang="it">Inferno</title> <author>Dante Alighieri</author> <year>1308</year> <price>30.00</price> </book> 

任何提示? 提前致谢。

尝试

 //book[title/@lang = 'it'] 

这写道:

  • 获取所有的book元素
    • 至less有一个title
      • 其中有一个属性lang
        • "it"的价值

你可能会觉得这很有帮助 – 这是Ronald Bourret撰写的一篇题为“XPath in Five Paragraphs”的文章。

但是诚实地说, //book[title[@lang='it']]和上面的内容应该是等价的,除非你的XPath引擎有问题。 因此,这可能是代码或示例XML中的东西,而您没有向我们展示 – 例如,您的示例是一个XML片段。 难道是根元素有一个名称空间,你不在你的查询计数? 而你只告诉我们,这是行不通的,但是你没有告诉我们你得到了什么结果。

多年以后,但是一个有用的select是使用XPath轴( https://www.w3schools.com/xml/xpath_axes.asp )。 更具体地说,你正在寻找使用后代轴。

我相信这个例子会诀窍:

 //book[descendant::title[@lang='it']] 

这使您可以select包含子title元素的所有book元素(不pipe嵌套深度如何),其中的语言属性值等于“it”。

我不能肯定地说这个答案是否与2009年有关,因为我并不是100%确定当时存在XPath Axes。 我可以确认的是,他们今天确实存在,我发现他们在XPath导航非常有用,我相信你也会。

 //book[title[@lang='it']] 

实际上相当于

  //book[title/@lang = 'it'] 

我尝试使用vtd-xml,这两个expression式吐出相同的结果…你使用什么xpath处理引擎? 我猜它符合性问题下面是代码

 import com.ximpleware.*; public class test1 { public static void main(String[] s) throws Exception{ VTDGen vg = new VTDGen(); if (vg.parseFile("c:/books.xml", true)){ VTDNav vn = vg.getNav(); AutoPilot ap = new AutoPilot(vn); ap.selectXPath("//book[title[@lang='it']]"); //ap.selectXPath("//book[title/@lang='it']"); int i; while((i=ap.evalXPath())!=-1){ System.out.println("index ==>"+i); } /*if (vn.endsWith(i, "< test")){ System.out.println(" good "); }else System.out.println(" bad ");*/ } } } 

尝试使用这个xPathexpression式:

 //book/title[@lang='it']/.. 

这应该给你所有的“it”lang的书籍节点

我会认为你自己的build议是正确的,但是XML是不是很有效。 如果您正在<root>[Your"XML"Here]</root>上运行//book[title[@lang='it']] ,那么免费的在线xPathtesting人员将会find预期的结果。