A co to?

W kursie https://jaktestowac.pl/course/pt1-mk3-podstawy-testow-automatycznych-w-selenium-i-python/ omawiamy szczegółowo podstawy XPath a w tym wpisie znajdziesz trochę bardziej skondensowane spojrzenie na ten temat. Nie obędzie się też bez zadań praktycznych – mimo iż jest to tylko ściąga 🙂 Przy okazji udało nam się przemycić nowe wyrażenie cheat sheet.

Czym jest XPath?

XPath jest językiem, który definiuje jak znaleźć różne informacje i elementy w plikach XML, HTML i innych, które opierają się na znacznikach.

TIP: XML (ang. Extensible Markup Language, co można przetłumaczyć na Rozszerzalny Język Znaczników) jest językiem znaczników, służącym do przechowywania danych. Jest on bardzo podobny do języka HTML, z tym wyjątkiem, że w XML mamy pełną dowolność jeśli chodzi o nazewnictwo znaczników. W języku HTML już takiej dowolności nie mamy, gdyż służy on do tworzenia stron internetowych i musi zawierać odpowiednie znaczniki poprawne dla przeglądarki internetowej, np <img> dla wyświetlania obrazów albo <a> dla linków. Przykładem dokumentu w formacie XML będzie poniższy kod, który opisuje nam książki w księgarni:

<bookstore>
  <book category="sci-fi">
    <title lang="en">Dune</title>
    <author>Frank Herbert</author>
    <year>1965</year>
    <price>45.00</price>
  </book>
  <book category="fantasy">
    <title lang="en">The Lord of the Rings</title>
    <author> J. R. R. Tolkien</author>
    <year>1954</year>
    <price>45.00</price>
  </book>
  <book category="drama">
    <title lang="en">Forrest Gump</title>
    <author>Winston Groom</author>
    <year>1986</year>
    <price>20.00</price>
  </book>
  <book category="sci-fi">
    <title lang="pl">Perfekcyjna Niedoskonałość</title>
    <author>Jacek Dukaj</author>
    <year>2004</year>
    <price>35.00</price>
  </book>
  <book category="sci-fi drama">
    <title lang="pl">Robot Bob</title>
    <author>Jacek Doe</author>
    <year>2000</year>
    <price>15.00</price>
  </book>
  <book category="dark fantasy, sci-fi, horror, western">
    <title lang="en">The Dark Tower: The Gunslinger</title>
    <author>Stephen King</author>
    <year>1987</year>
    <price>30.00</price>
  </book>
  <book category="dark fantasy, sci-fi, horror, western">
    <title lang="en">The Dark Tower II: The Drawing of the Three</title>
    <author>Stephen King</author>
    <year>1982</year>
    <price>30.00</price>
  </book>
  <book category="gothic novel, psychological horror">
    <title lang="en">The Shining</title>
    <author>Stephen King</author>
    <year>1977</year>
    <price>45.00</price>
  </book>
  <magazine category="IT">
    <title lang="en">How to program stuff</title>
    <author>John Doe</author>
    <year>1991</year>
    <price>10.00</price>
  </magazine>
</bookstore>

Język XPath, jak każdy język, składa się z określonych wyrażeń i wyrażenia w tym języku muszą być budowane w określony sposób. Poniżej zamieściliśmy kilka najważniejszych wyrażeń wchodzących w skład wyrażeń XPath (bez obaw, zaraz po nich poćwiczymy na przykładach).

Wyrażenia do znajdowania węzłów na określonych poziomach:

Wyrażenie Znaczenie
/ wyszukanie węzła począwszy od najwyższego poziomu (root)
// zaznaczenie węzłów w dokumencie bez względu gdzie się znajdują
. zaznaczenie obecnego węzła
.. zaznaczenie rodzica (węzła nadrzędnego) w stosunku do obecnego węzła
@lang zaznaczenie atrybutu o nazwie “lang” węzła
//book zaznaczenie wszystkich węzłów typu “book”, bez względu gdzie się znajdują
//book/title zaznaczenie wszystkich węzłów typu “title”, które mają rodzica typu “book”

Predykaty – czyli wyszukiwanie węzłów o określonych właściwościach:

Wyrażenie Znaczenie
/bookstore/book[1] wyszukanie pierwszego węzła typu “book”, którego rodzicem jest “bookstore”
/bookstore/book[last()] wyszukanie ostatniego węzła typu “book”, którego rodzicem jest “bookstore”
//book/title[@lang] wyszukanie w dowolnym miejscu węzła typu “title” o atrybucie “lang”, którego rodzicem jest “book”
//book/title[@lang="pl"] wyszukanie w dowolnym miejscu węzła typu “title” o atrybucie “lang” o wartości “pl”, którego rodzicem jest “book”
/bookstore/book[price>35.00] wyszukanie węzła typu “book”, który posiada element “price” o wartości większej niż 35.00

Inne przydatne konstrukcje:

Wyrażenie Znaczenie
* wyszukanie dowolnego elementu
@* wyszukanie dowolnego atrybutu
//book/title | //book/author wyszukanie wszystkich węzłów typu “title” oraz wszystkich węzłów typu “author”
//book/title[contains(text(),'Lord')] wyszukanie wszystkich węzłów typu “title”, które zawierają w sobie ciąg znaków “Lord”
//book[contains(@category,'drama')] wyszukanie wszystkich węzłów typu “book”, które posiadają atrybut “category” zawierający w sobie ciąg znaków “drama”

 

Przykładowe zadania z XPath

Zacznijmy od kilku prostych przykładów wyrażeń w oparciu o kod księgarni powyżej aby lepiej zrozumieć jak używać XPath. Bardzo często dany problem ma więcej niż jedno rozwiązanie.
Do testowania wyrażeń XPath polecamy użyć jednej z wielu dostępnych stron na przykład https://codebeautify.org/Xpath-Tester. Wystarczy wkleić w pole XML Input kod XML lub HTML, następnie w polu XPath Expression umieścić wyrażenie XPath po czym kliknąć w przycisk TEST XPATH. W polu po prawej stronie pojawi się wynik.

Zachęcamy tez do testowania z nami poniższych rozwiązań i eksperymentowania 🙂

  1. Jak wyszukać wszystkie książki w księgarni?
    //book
    /bookstore/book
  2. Jak wyszukać wszystkie tytuły książek?
    //book/title
  3. Jak wyszukać wszystkie książki, które są autorstwa Franka Herberta?
    //book[author="Frank Herbert"]
  4. Jak wyszukać wszystkie tytuły książek, które są napisane w Języku polskim?
    //book/title[@lang="pl"]
  5. Jak wyszukać wszystkich autorów książek, którzy mają na imię Jacek?
    //book/author[contains(text(),'Jacek')]
  6. Jak wyszukać pierwszą książkę, której cena wynosi 45.00?
    /bookstore/book[price=45.00][1]
  7. Jak wyszukać wszystkie tytuły książek i magazynów, które są w języku angielskim?
    //title[@lang='en']
    //*/title[@lang='en']
  8. Jak wyszukać wszystkie pozycje (książki i magazyny), które są w języku angielskim?
    //*/title[@lang='en']/..
    //title[@lang='en']/..
  9. Jak wyszukać wszystkie książki z gatunki sci-fi oraz fantasy?
    //book[contains(@category,'sci-fi') or contains(@category,'fantasy')]
  10. Jak wyszukać wszystkie książki z przedziału cenowego od 30.00 do 40.00?
    //book[price >= 30.00 and price <= 40.00]
  11. Jak wyszukać wszystkie tytuły książek z przedziału cenowego od 30.00 do 40.00?
    //book[price >= 30.00 and price <= 40.00]/title

Jak możemy zauważyć w powyższych przykładach, warunki możemy też łączyć słowami kluczowymi and oraz or.

Teraz Ty

Zapoznaliśmy się ze składnią języka XPath oraz zobaczyliśmy jak wyglądają przykładowe konstrukcje do znajdowania różnego typu elementów. Teraz nadeszła pora aby przećwiczyć zdobytą wiedzę. Poniżej zamieściliśmy kilka zadań, które chcemy abyś rozwiązał w oparciu o XMLa początku kursu i przy użyciu strony do testowania wyrażeń XPath. Gdybyś miał problem z jakimkolwiek z punktów to sugerujemy najpierw przejrzeć jeszcze raz powyższe przykłady a w ostateczności zerknąć do rozwiązań, które zamieścimy poniżej 🙂 Powodzenia!

  1. Jak wyszukać wszystkie książki napisane przez Stephena Kinga po roku 1980?
  2. Jak wyszukać dowolną pozycję (książki i magazyny), których cena jest niższa niż 30.00 oraz język jest “en”?
  3. Jak wyszukać wszystkie książki z gatunku “western” napisane przez Stephena Kinga?

Poniżej znajdują się rozwiązania do zadań.

  1. //book[author = "Stephen King" and year > 1980]/title
  2. //*[price < 30.00 and title[@lang="en"]]
  3. //book[contains(@category, "western") and author="Stephen King"]

Jak przetestować XPath na dowolnej stronie internetowej?

Do tego celu potrzebna będzie dowolna przeglądarka i jej konsola, która znajduje się w zestawie narzędzi deweloperskich, które mona otworzyć używając klawisza F12. Aby przetestować dowolne wyrażenie XPath należy użyć funkcji $x('xpath'), która przyjmuje jako argument wyrażenie XPath.
Przykład:

$x('//*[@id="login_form"]/h1')

Więcej praktycznych przykładów użycia możecie znaleźć w kursie Podstawy Testów Automatycznych w Selenium i Python cz. 3 – Sztuka znajdowania elementów – XPath.