tags:

views:

865

answers:

2

Suppose I have the following 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>

I would like to do an xpath that gets back all book nodes that have a title node with a language attribute of "it".

My attempt looked something like this:

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

But that didn't work. I expect to get back the nodes:

<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>

Any hints? Thanks in advance.

+4  A: 

Try

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

This reads:

  • get all book elements
    • that have at least one title
      • which has an attribute lang
        • with a value of "it"

You may find this helpful — it's an article entitled "XPath in Five Paragraphs" by Ronald Bourret.

But in all honesty, //book[title[@lang='it']] and the above should be equivalent, unless your XPath engine has "issues." So it could be something in the code or sample XML that you're not showing us.

lavinio
mm, interesting read.
meder
+1  A: 
//book[title[@lang='it']]

is actually equivalent to

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

I tried it using vtd-xml, both expressions spit out the same result... what xpath processing engine did you use? I guess it has conformance issue Below is the code

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 ");*/

      }
  }
}
vtd-xml-author
+1 that its a compliance issue and that the syntax generates the same nodeset. Similar code in C# also works.
Zach Bonham
-1: Mr. Zhang, I was trying to do you a favor by removing code not relevant to the question. It allowed me to not downvote you, which I now feel I have to. Note that no other answer included code to call call the query.
John Saunders