Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP][xpath, xml, php] dostęp do elementu po ścieżce
Forum PHP.pl > Forum > Przedszkole
borovsky
wiecie, jak w simplexml (php) mieć dostęp do node: glowny.dziecko.jakistam, gdzie xml jest :
<item id="glowny">
<item id="dziecko">
<item id="jakistam">
</item>
</item>
</item>

?

używam simplexml

jak napisać odwołanie xpath: coś na wzór:

getPathByAttribute(["id"], "glowny.dziecko.jakistam")
normalnie to notacją kropkową tworzy się ścieżkę bazującą na nazwach węzłów, a nie na atrybucie.
erix
Ale po co tak, skoro identyfikator jest unikalny w całym dokumencie?
borovsky
troszeczkę inaczej podchodzę do problemu. id składa się ze ścieżki atrybutów id root.child.child.node
sam atrybut id nie jest unikalny, zamierzam mieć też: root.node, root.child.node, root.child.child.child.child

także ścieżka składająca się z szeregu wartości atrybutów id węzłow: od root schodząco do węzła pożądanego.
erix
Cytat
troszeczkę inaczej podchodzę do problemu. id składa się ze ścieżki atrybutów id root.child.child.node
sam atrybut id nie jest unikalny

A być powinien.
thek
Źle rozumiesz XML i pojęcie identyfikatora. Identyfikator jest ZAWSZE unikalny wartości elementów, nazwy w strukturze mogą się dublować. Sam plik XML ma zawsze strukturę:
<element_root>
.
elementy
.
</element_root>
gdzie elementy przyjmują formę
<element atrybut="jego_wartosc">
</element>
lub
<element atrybut="jego_wartosc" />
przy czym 1 wariant jest stosowany, gdy ma zawierać głębszą strukturę, gdyż jeśli tylko pojedynczą, to można go zamienić do formy 2 (o ile te dzieci same nie mają atrybutów).
Twoja wersja więc ma sens tylko gdy dane dla dzieci są wspólne z rodzicem. Przykładem może być blokowisko. Jest jakieś jedno (element root), ale na nim są ulice (element 1 rzędu), których zapewne jest kilka. Ulica może wystąpić jako id, gdyż jest jednoznaczna (ale tylko do poziomu miasta! Jeśli jest kilka miast to już nie jest unikatowa). Następnym zagnieżdżeniem byłby numer bloku przy danej ulicy. Ale to już NIE MOŻE być id (gdyż ten sam numer może wystąpić na kilku ulicach). Można jednak przekształcić strukturę XML, by numer bloku był razem z nazwą ulicy, gdyż jest to już jednoznaczne. Jest to jednak gorsze rozwiązanie, gdyż upychamy możliwą dużą strukturę do płytko zagnieżdżonej, przez co wyszukiwanie jest za każdym razem na dużych zbiorach.
Stąd lepsze rozwiązanie to
  1. <blokowisko>
  2. <ulica id="Piotra">
  3. <numer blok="1" />
  4. <numer blok="2" />
  5. </ulica>
  6. <ulica id="Pawła">
  7. <numer blok="1" />
  8. </ulica>
  9. <ulica id="Roberta">
  10. <numer blok="1" />
  11. <numer blok="2" />
  12. <numer blok="3" />
  13. </ulica>
  14. </blokowisko>

zamiast tego
  1. <blokowisko>
  2. <ulica id="Piotra_1" />
  3. <ulica id="Piotra_2" />
  4. <ulica id="Pawła_1" />
  5. <ulica id="Roberta_1" />
  6. <ulica id="Roberta_2" />
  7. <ulica id="Roberta_3" />
  8. </blokowisko>
Do ulicy Piotra 1 w przypadku 1 odnieść się musielibyśmy:
/blokowisko/ulica[id=Piotra]/numer[blok=1]
a drugim:
/blokowisko/ulica[id=Piotra_1]
Niby drugi krótszy i fajniejszy, ale w przypadku rozbudowy struktury, pogłębianiu jej lub rozszerzaniu musimy mocno ingerować i zwracać uwagę co jest unikatowe, co nie i pojawia się o wiele więcej problemów z jednoznacznymi odwołaniami. Twój sposób jest zły z racji tego, że chcesz do wszystkiego id walnąć, nawet do numeru bloku zachowując prostotę struktury 1. W efekcie odwołanie do elementu z id=1 wywali błąd, bo jest takich kilka, co jest ewidentnym błędem programisty. Takie coś jest zwyczajnie zabronione w poprawnym XML.

A co gdy oprócz bloków będziesz chciał wrzucać jeszcze piętra, numery mieszkań i nazwiska lokatorów? Stworzysz wszystko pooddzielane lub poupychasz wszystko do struktury pokroju:
  1. <blokowisko>
  2. <ulica id="Piotra" numer="1" pietro="2", mieszkanie="5", wlasciciel="Kowalski" />
  3. </blokowisko>
Zauważ, że można, ale wszystko Ci się do jednego ogromnego zbioru sprowadzi, w którym na dodatek zastosowanie ulicy jako id jest po prostu błędem (nie jest on unikalny... to musi stać się zwykłym atrybutem) i którego przeszukiwanie po wszystkich atrybutach może być obciążające serwer. taka struktura jest po prostu niewygodna.
borovsky
  1. <data>
  2. <store>
  3. <category name="pamiątki" id="souvenirs">
  4. <category name="płaskorzeźby" id="plasko">
  5. <item name="Pani z pieskiem" id="pani_piesek" price="25" avaliable="24" technology="farba" url="z pieskiem.jpg">
  6. <desc>
  7. Ładny piesek łasi się do swojej pani.
  8. </desc>
  9. </item>
  10. <item name="Pani z kotkiem" id="pani_kotek" price="22" avaliable="5" technology="spray" url="z kotem.jpg">
  11. <desc>
  12. Ładny kotek łasi się do swojej pani.
  13. </desc>
  14. </item>
  15. </category>
  16. <category name="figurki" id="figury">
  17. <item name="Figurka Piesek" id="piesek" price="9" avaliable="150" technology="wosk" url="piesek.jpg">
  18. <desc>
  19. Bardzo ładna woskowa figurka.
  20. </desc>
  21. </item>
  22. </category>
  23. </category>
  24. <category name="Obrazy" id="obrazy">
  25. <category name="Wnętrza" id="wnetrza">
  26. <item name="Gra Świateł" id="swiatla" price="8" avaliable="118" technology="photo" url="gra świateł.jpg"/>
  27. </category>
  28. </category>
  29. <category name="Kategoria Jakastam" id="costam">
  30. <category name="Książki" id="book">
  31. <item name="Zanim Powiesz Kocham" price="20" avaliable="4" technology="druk" id="kocham" url="kocham.jpg"/>
  32. </category>
  33. </category>
  34. </store>
  35. </data>

w tym xml mam sklep z kilkoma pozycjami, może źle nazwałem: nie chodzi w takim razie o id, lecz o identyfikacje produktu podając ścieżkę: obrazy.wnetrza.swiatla
wlasnie chodzi tutaj o adres jak w strukturze katalogów systemowych: przecież plik w folderze costam, ktory jest w folderze subcostam, a nazywa sie pliczek.txt nie ma adresu pliczek.txt, bo taki pliczek moze jeszce gdzies istniec w innym folderze.
dodatkowo: osobiście upieram się na jednolity (moze byc id) bo przeciez ilosc poziomów w takim sklepie (zagnieżdżanie podakategorii) jest zmienna. Rozumiem XML, ale jak widac źle się wyraziłem. w każdym razie myślałem, że nie trzeba tworzyc xpath w formie:
/item[@id='obrazy']/item[@id='wnetrza']/item[@id='swiatla'] tylko cos na wzór (chodzi o jakas krótką formę): obrazy.wnetrza.swiatla
oczywiscie tę długą forme jestem w stanie sobie wygenerować automatycznie, nawet mogę sobie napisać funkcję bez użycia xpath, jednak szukam uniwersalnych rekomendowanych rozwiązań.
thek
Zauważ, że w takiej strukturze ów id JEST jednoznaczny i możesz odwołać się do niego poprzez id smile.gif
borovsky
dzięki smile.gif
mi jednak zależy na dostępie poprzez złożenie ścieżki.

mam jednak takie inne pytanie:
jak z takiego xml:
  1. <xml>
  2. <nazwa id="costam">
  3. <costam2/>
  4. </nazwa>
  5. </xml>


jak ułożyć xpath, który będzie (sprawa dotyczy struktury z tego tematu) miał taki algorytm
podaję ścieżkę: xml.costam.costam2
a xpath będzie każdy element sprawdzał:

1.czy node ma atrybut id o takiej wartości
2.jeśli nie, to czy ma nazwa o takiej wartości
erix
Cytat
mi jednak zależy na dostępie poprzez złożenie ścieżki.

To się w końcu zdecyduj - przez własną konwencję nazewnictwa, czy przez XPath? Bo o ile pamiętam, to XPath miał nieco inną składnię niż ta, którą podajesz.

Wg tej Twojej, trzeba by było najpierw napisać odpowiedni parser, który pozamienia znaki, dopiero potem poszuka po xpath.

Cytat
nawet mogę sobie napisać funkcję bez użycia xpath, jednak szukam uniwersalnych rekomendowanych rozwiązań.

Wytłumacz mi jedno: po co sobie utrudniasz życie? Przecież parsując to coś i tak musisz wygenerować XPath, niezależnie od Twojej składni

Cytat
/item[@id='obrazy']/item[@id='wnetrza']/item[@id='swiatla']

Ile razy trzeba Ci jeszcze tłumaczyć, że ID musi być unikalne? Jak nie będzie, to nie mamy nawet o czym dyskutować, gdyż tak ma być i niektóre parsery będą wariować jak znajdą kilka takich samych identyfikatorów?

Cytat
1.czy node ma atrybut id o takiej wartości
2.jeśli nie, to czy ma nazwa o takiej wartości

Jak pisałem, raczej czeka Cię pisanie własnego parsera.
borovsky
dzięki wam za pomoc.
moje utrudnianie sobie życia polega na tym, że uczę się, a jeśli uczę się sam, to nie mogę cały czas robić po najlżejszej linii oporu. Oczywiście, poradziłem sobie sam pisząc kod, ale porównam to do mojego doświadczenia:
chciałem robić aplikacje RIA we flashu. (a siedzę w tym 5 lat) jednak po jakims czasie zdecydowałem się utrudnić sobie życie - próbując poznać do czego służy Adobe Flex. No i teraz robię w Flex i gdyby nie utrudnianie sobie życia - męczyłbym się w flash. Jeszcze jedno pytanie: czy atrybut ID jest zastrzeżony dla XML? czy nie może być to po prostu jakis sobie atrybut?
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.