Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get nodes where child node contains an attribute

Tags:

xml

xpath

People also ask

How do I select the first child in XPath?

The key part of this XPath is *[1] , which will select the node value of the first child of Department .

How do you navigate from parent to child in XPath?

Start by writing out the selenium Xpath for the parent and then traverse to desired object using back slashes like so; Xpath Parent written as //div[@class='region region-navigation' using our previously shown syntax. Now you start to traverse through the HTML nodes down to desired object.

What is child :: In XPath?

As defined in the W3 XPath 1.0 Spec, " child::node() selects all the children of the context node, whatever their node type." This means that any element, text-node, comment-node and processing-instruction node children are selected by this node-test.


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 -- for example, your sample is an XML fragment. Could it be that the root element has a namespace, and you aren't counting for that in your query? And you only told us that it didn't work, but you didn't tell us what results you did get.


Years later, but a useful option would be to utilize XPath Axes (https://www.w3schools.com/xml/xpath_axes.asp). More specifically, you are looking to use the descendants axes.

I believe this example would do the trick:

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

This allows you to select all book elements that contain a child title element (regardless of how deep it is nested) containing language attribute value equal to 'it'.

I cannot say for sure whether or not this answer is relevant to the year 2009 as I am not 100% certain that the XPath Axes existed at that time. What I can confirm is that they do exist today and I have found them to be extremely useful in XPath navigation and I am sure you will as well.


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

      }
  }
}

I would think your own suggestion is correct, however the xml is not quite valid. If you are running the //book[title[@lang='it']] on <root>[Your"XML"Here]</root> then the free online xPath testers such as one here will find the expected result.


Try to use this xPath expression:

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

That should give you all book nodes in "it" lang