Jak wybrać elementy podrzędne o dowolnej głębokości za pomocą XPath?

101

Załóżmy, że mam to (uproszczone):

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

Następnie mogę wybrać przycisk przesyłania za pomocą XPath //form[@id='myform']/input[@type='submit']. Wspaniały.

Jednak moje szablony mogą się zmienić i chcę być elastyczny co do głębokości, w jakiej znajduje się przycisk przesyłania. Można go umieścić w tabeli, na przykład:

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

Wiem, że mogę wybierać elementy, które są wnukami, ale nie mogę wybrać wnuk-pradziadków o jakiejkolwiek głębi. Na przykład:

  • //form[@id='myform']/*/input[@type='submit'] wybiera tylko wnuki, nie ma dalszych głębin.
  • //form[@id='myform']/*/*/input[@type='submit'] wybiera tylko prawnuki, nie ma dalszych ani mniejszych głębokości.
  • //form[@id='myform']/**/input[@type='submit'] nie jest poprawny.

Jak więc niezawodnie wybrać ten przycisk przesyłania bez używania identyfikatorów elementów?

gertvdijk
źródło

Odpowiedzi:

159

Jesteś prawie na miejscu. Po prostu użyj:

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

//Skrót może być również stosowany wewnątrz wyrażenia.

nwellnhof
źródło
C # wydaje się nie rozumieć tej notacji. //form//inputzwraca wartość null w C #, podczas gdy Chrome może znaleźć 35 danych wejściowych przy użyciu tej samej ścieżki xpath
Achilles
1
Mój ostatni komentarz jest omawiany tutaj: stackoverflow.com/questions/23232671/ ...
Achilles
14

Jeśli używasz XmlDocument i XmlNode.

Mówić:

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

Posługiwać się:

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

To zależy od używanego narzędzia. Ale .// wybierze dowolne dziecko, dowolną głębokość z węzła odniesienia.

sk
źródło
Działa dobrze w programie Powershell przy użyciu polecenia SelectSingleNode na określonym wcześniej wyodrębnionym węźle XML.
Gizmo3399
9
//form/descendant::input[@type='submit']
luis long
źródło
7
dodaj do tego jakiś opis.
piyushj
0

Możesz to również zrobić za pomocą selektorów css:

form#myform input[type='submit']

spacja między elementami w elektorze css oznacza wyszukiwanie danych wejściowych [type = 'submit'], które elementy na dowolnej głębokości formularza nadrzędnego # element myform

Mahsum Akbas
źródło