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 soupRyū Murakami2005100.00The Wind-Up Bird ChronicleHaruki Murakami199455.99How to prepare your garden for Eternal AutumnBethany Covenant199821.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 soupRyū Murakami2005100.00,
In the miso soup,
Ryū Murakami,
2005,
100.00,
The Wind-Up Bird ChronicleHaruki Murakami199455.99,
The Wind-Up Bird Chronicle,
Haruki Murakami,
1994,
55.99,
How to prepare your garden for Eternal AutumnBethany Covenant199821.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.
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
DisciplineDiscipline: Way of freedom120.00Discipline II125.00Heavy matter185499.99Codex Nitriensis999.00Codex Zacynthius999.00Codex XCodex 10999.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 matter185499.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
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.
przepraszam ale poprzedni komentarz dotyczył zadania 0 tego gdzie mymy znaleźćatrybuty rodzica którego dzieckiem jest element title o wartośći “Heavy..”.
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:
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())
//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 😉
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.
przepraszam ale poprzedni komentarz dotyczył zadania 0 tego gdzie mymy znaleźćatrybuty rodzica którego dzieckiem jest element title o wartośći “Heavy..”.
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 (czylibook
), 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 funkcjicontains()
) 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()
)Zdążyłem się przekonać, że wielkośc liter ma znaczenia. Dzięki za odpowiedź.
Nie ma sprawy 🙂
‘//unknown/following-sibling::*’ -dlaczego zwraca pusty rekord?
//unknown/following-sibling::*
zwraca 0 wyników, gdyż elementunknown
nie posiada żadnego elementu po sobie na tym samym poziomie. Tzn w drzewie, wbookstore
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 elementunknown
, z racji żeunknown
występuje polost
😉Do zadania 2 pasuje mi też: //lost//child::title
Bardzo dobra dedukcja – to też jest wyrażenie, które jest ok 😀