151

Suppose I have this (simplified):

<form id="myform">
    <!-- some input fields -->
    <input type="submit" value="proceed"/>
</form>

Then I can select the submit button by XPath //form[@id='myform']/input[@type='submit']. Great.

However, my templates might change and I want to be flexible in the depth in which the submit button is located. It might be put in a table, like this:

<form id="myform">
    <!-- some input fields -->
    <table><tr><td>
           <input type="submit" value="proceed"/>
    </td></tr></table>
</form>

I know I can select elements which are grandchildren, but I can't select grand-grand-grand-...-childeren of any depth. E.g.:

  • //form[@id='myform']/*/input[@type='submit'] only selects grand-children, no further depths.
  • //form[@id='myform']/*/*/input[@type='submit'] only selects grand-grand-children, no further or less depths.
  • //form[@id='myform']/**/input[@type='submit'] is not valid.

So, how do I select this submit button reliably without using element IDs?

gertvdijk
  • 24,056
  • 6
  • 41
  • 67

3 Answers3

222

You're almost there. Simply use:

//form[@id='myform']//input[@type='submit']

The // shortcut can also be used inside an expression.

nwellnhof
  • 32,319
  • 7
  • 89
  • 113
  • C# doesn't seem to understand this notation. `//form//input` returns null in C# while Chrome can find 35 inputs using the same xpath – Achilles Mar 22 '15 at 07:27
  • 1
    My last comment is discussed here: http://stackoverflow.com/questions/23232671/xpath-selects-in-htmlagilitypack-dont-work-as-expected – Achilles Mar 22 '15 at 07:30
  • Check out this site for more XPath commands - https://www.scientecheasy.com/2019/08/xpath-axes.html/ – Herker Apr 08 '21 at 12:15
23

If you are using the XmlDocument and XmlNode.

Say:

XmlNode f = root.SelectSingleNode("//form[@id='myform']");

Use:

XmlNode s = f.SelectSingleNode(".//input[@type='submit']");

It depends on the tool that you use. But .// will select any child, any depth from a reference node.

s k
  • 4,342
  • 3
  • 42
  • 61
11
//form/descendant::input[@type='submit']
dur
  • 15,689
  • 25
  • 79
  • 125
luis long
  • 111
  • 1
  • 2