XPath – Zadania, część 4 – Axes

Jest to czwarta część z cyklu XPath – Zadania, który ma na celu przetestować Twoją wiedzę z zakresu wyrażeń XPath na różnych przykładach. Zadania tu zebrane dotyczą głównie Axes (osi), ale bazują też na wyrażeniach poruszonych w poprzednich częściach. XML, na którym bazują zadania, wraz z aplikacją pozwalającą na testy wyrażeń XPath, dostępny jest pod adresem XPath Playground. Teraz, gdy mamy już wszystkie narzędzia gotowe możemy przystąpić do rozwiązywania zadań…

Zatem do dzieła! 🙂

P.S. Ściąga z wyrażeń XPath dostępna jest na stronie XPath cheat sheet 😉

Zadanie 1 – Axes i dzieci

Znajdź wszystkie elementy-dzieci (ang. child/children), które znajdują się w elemencie lost.

Oczekiwany wynik

      
         In the miso soup
         Ryū Murakami
         2005
         100.00
      
      
         The Wind-Up Bird Chronicle
         Haruki Murakami
         1994
         55.99
      
      
         How to prepare your garden for Eternal Autumn
         Bethany Covenant
         1998
         21.00
      
   
Podpowiedź
Do znajdowania elementu-dziecka służy operator child::.
Rozwiązanie
//child::lost

Zadanie 2 – Axes i dzieci

Znajdź wszystkie elementy-dzieci (ang. child/children) typu title, które znajdują się w elemencie lost.

Oczekiwany wynik
In the miso soup,
The Wind-Up Bird Chronicle,
How to prepare your garden for Eternal Autumn
Podpowiedź
Do znajdowania elementu-dziecka służy operator child::.
Rozwiązanie 1
//lost/*/child::title
Rozwiązanie 2
//lost//title

Zadanie 3 – Axes i dzieci

Znajdź wszystkie elementy-dzieci (ang. child/children), które znajdują się w elemencie book, którego title ma wartość Dune.

Oczekiwany wynik
Dune,
Frank Herbert,
1965,
45.00

Podpowiedź
Do znajdowania elementu-dziecka służy operator child::.
Rozwiązanie 1
//book[title='Dune']/child::*
Rozwiązanie 2
//book[title='Dune']/*

Zadanie 4 – Axes i potomkowie

Znajdź wszystkich potomków (ang. descendant), którzy znajdują się w elemencie lost.

Oczekiwany wynik

         In the miso soup
         Ryū Murakami
         2005
         100.00
      ,
In the miso soup,
Ryū Murakami,
2005,
100.00,

         The Wind-Up Bird Chronicle
         Haruki Murakami
         1994
         55.99
      ,
The Wind-Up Bird Chronicle,
Haruki Murakami,
1994,
55.99,

         How to prepare your garden for Eternal Autumn
         Bethany Covenant
         1998
         21.00
      ,
How to prepare your garden for Eternal Autumn,
Bethany Covenant,
1998,
21.00

Podpowiedź
Do znajdowania elementu-potomka służy operator descendant::.
Rozwiązanie
//lost/descendant::*

Zadanie 5 – Axes i rodzeństwo

Znajdź wszystkie elementy-rodzeństwo (ang. siblings) w stosunku do elementu book, które znajduje się w elemencie unknown.

Oczekiwany wynik

         Discipline II
         125.00
      ,

         Heavy matter
         1854
         99.99
      ,

         Codex Nitriensis
         999.00
      ,

         Codex Zacynthius
         999.00
      ,

         Codex X
         
            Codex 10
         
         999.00
      

Podpowiedź
Do znajdowania elementów-rodzeństwa służy operator following-sibling::.
Rozwiązanie
//unknown/book/following-sibling::*

Zadanie 6 – Axes i rodzeństwo

Znajdź wszystkie elementy-rodzeństwo (ang. siblings) w stosunku do elementu title, który ma wartość Dune.

Oczekiwany wynik
Frank Herbert,
1965,
45.00
Podpowiedź
Do znajdowania elementów-rodzeństwa służy operator following-sibling::.
Rozwiązanie
//title[text()='Dune']/following-sibling::*

Zadanie 7 – Axes i elementy następujące

Znajdź wszystkie elementy następujące po pierwszym elemencie book, który znajduje się w elemencie unknown.

Oczekiwany wynik

         Discipline II
         125.00
      ,
Discipline II,
125.00,

         Heavy matter
         1854
         99.99
      ,
Heavy matter,
1854,
99.99,

         Codex Nitriensis
         999.00
      ,
Codex Nitriensis,
999.00,

         Codex Zacynthius
         999.00
      ,
Codex Zacynthius,
999.00,

         Codex X
         
            Codex 10
         
         999.00
      ,
Codex X,

            Codex 10
         ,
Codex 10,
999.00

Podpowiedź
Do znajdowania elementów następujących po danym elemencie służy operator following::.
Rozwiązanie
//unknown/book[1]/following::*

Zadanie 8 – Axes i rodzice

Znajdź rodzica (ang. parent) elementu typu book, którego element title ma wartość Heavy matter.

Oczekiwany wynik

      
         Discipline
         
            Discipline: Way of freedom
         
         120.00
      
      
         Discipline II
         125.00
      
      
         Heavy matter
         1854
         99.99
      
      
         Codex Nitriensis
         999.00
      
      
         Codex Zacynthius
         999.00
      
      
         Codex X
         
            Codex 10
         
         999.00
      
   

Podpowiedź
Do znajdowania rodziców danego elementu służy operator parent::.
Rozwiązanie
//book[title="Heavy matter"]/parent::*

Zadanie 9 – Axes i rodzice

Znajdź rodzica (czyli book) elementu title, który ma wartość Heavy matter.

Oczekiwany wynik

         Heavy matter
         1854
         99.00

Podpowiedź 1
Do znajdowania rodziców danego elementu służy operator parent::.
Podpowiedź 2
Do pobierania wartości danego elementu służy funkcja text().
Podpowiedź 3
Do znalezienia elementu o danej nazwie służy konstrukcja [text()="Heavy matter"].
Rozwiązanie 1
//title[text()="Heavy matter"]/parent::*
Rozwiązanie 2
//title[text()="Heavy matter"]/..

Zadanie 10 – Axes i atrybuty

Znajdź atrybuty rodzica (czyli book) elementu title, który ma wartość Heavy matter.

Oczekiwany wynik
hard
Podpowiedź 1
Zadanie można rozwiązać na co najmniej dwa sposoby – jeden przy użyciu operatora attribute::, a drugi z wykorzystaniem @.
Rozwiązanie 1
//book[title="Heavy matter"]/attribute::*
Rozwiązanie 2
//book[title="Heavy matter"]/@*

Zadanie 11 – Axes i atrybuty

Znajdź elementy title oraz year wszystkich elementów typu magazine.

Oczekiwany wynik
How to program stuff,
1991,
How to program other stuff,
1992,
How to prepare your garden for Eternal Autumn,
1998
Podpowiedź
Do łączenia wyrażeń XPath służy operator |.
Rozwiązanie 2
//magazine/title | //magazine/year

9 komentarzy

  1. Odpowiedz do zadania 9go jest wydaje mi się nie do końca poprawna. Zadziała co prawda w przypadku przykładowego dokumetnu.
    W zadaniu mamy znaleźć rodzica elementu title o który ma wartość Heavy matter..
    Dla przypadku gdy jededynym elementem, który ma w sobie element title o wartości ” Heavy …” działa,
    Natomiast w przypadku gdy mamy inny element ktorego dzieckiem jest
    title =”Heavy …” już nie działa

    Wydaje mi się, że odpowiedź powinna być następująca:
    //title[text()=”Heavy matter”]/parent::*/attribute::*’

    Dodalem do dokumentu element typu magazine, ktory ma dziecko title = “Heavy matter” i atrybut typu cover = “soft”.W takim przypadku prezentowana w odpowiedzi formula nie znajduje mi parametru soft a chyba powinna.

    Avatar aaa
      1. Twoja odpowiedź jest poprawna, jesli chcielibyśmy atrybuty wszystkich rodziców, którzy zawierają w sobie dany title, tzn:
        //title[text()=”Heavy matter”]/parent::*/attribute::*

        My w zadaniu 10 zaczynamy poszukiwania elementu title, ale już od poziomu rodzica (czyli book), dlatego nie musimy później używać:
        //book[title="Heavy matter"]/attribute::*

        Dla przykładu, zmieniając na poszukiwania tytułu z Dark (i bazując na funkcji contains()) dostaniemy prawie same wyniki w obu przypadkach:

        //title[contains(text(), "the")]/parent::*/attribute::*
        //book[contains(title, "the")]/attribute::*

        Prawie, gdyż pierwsze wyrażenie nie uwzględnia w sobie informacji o typie rodzica (jest po prostu bardziej ogólne), ale oba wyrażenia zwracają atrybuty rodziców 😉 (PS. wielkośc liter ma znaczenie w funkcji contains())

        Krzysiek Kijas Krzysiek Kijas
    1. //unknown/following-sibling::* zwraca 0 wyników, gdyż element unknown nie posiada żadnego elementu po sobie na tym samym poziomie. Tzn w drzewie, w bookstore są następujące elementy w kolejności:
      shelves, ordered, lost, unknown. unknown jest ostatni więc nic więcej nie zostanie zwrócone.

      Dla przykładu, //lost/following-sibling::* zwróci element unknown, z racji że unknown występuje po lost 😉

      Krzysiek Kijas Krzysiek Kijas

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *