Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] Odczyt XML
Forum PHP.pl > Forum > Przedszkole
Puchatek
Dzień dobry, mam pewien problem dotyczący odczytu pliku XML.
Posiadam poniższą strukturę (urywek kodu) - standard ceneo.
  1. <offers>
  2. <o id="47" url="url" price="24.47" stock="32" weight="0.027">
  3. <cat><![CDATA[Kategoria]]></cat>
  4. <name><![CDATA[Nazwa]]></name>
  5. <imgs>
  6. <main url="link"/>
  7. <i url="link"/>
  8. </imgs>
  9. <desc><![CDATA[OPIS]]></desc>
  10. <attrs>
  11. <a name="Producent"><![CDATA[Producent]]></a>
  12. <a name="Kod_Producenta"><![CDATA[Kod]]></a>
  13. <a name="EAN"><![CDATA[0000000000000]]></a>
  14. </attrs>
  15. </o>
  16. </offers>


Moim zamiarem jest przeszukanie całego pliku XML - wyszukanie w nim odpowiedniego numeru EAN a następnie pobranie ceny produktu, który ma ten EAN przypisany.
Oto częśc mojego kodu:
  1. $oFile = file_get_contents('Adres do XML');
  2. $oSimpleXmlObject = new SimpleXmlElement($oFile);
  3. $oImageSection = $oSimpleXmlObject->xpath('/o/attrs/a["name"]=EAN[.='.$ZmiennaEAN.']/parent::*');
  4. foreach($oImageSection[0]->o['price'] as $oImage)
  5. {
  6. }


Chodzi mi dokładniej o pomoc w zapisaniu ścieżki. Nie mam problemu kiedy każdy parametr jest w osobnym znaczniku. Natomiast tutaj w jednym znaczniku <a> jest name="Producent", name="Kod_Producenta", name="EAN". W jaki sposób to zapisać?
SmokAnalog
Nie jestem ekspertem w XPath, ale takie coś działa:

Kod
//o[descendant::attrs/a[@name='Producent' and text()='abc']][descendant::attrs/a[@name='Kod_Producenta' and text()='abc']][descendant::attrs/a[@name='EAN' and text()='abc']]


Być może można to uprościć. Działa jeśli oczywiście wstawisz coś własnego pod "abc".
Puchatek
Zastosowałem taki zapis:
  1. $oImageSection = $oSimpleXmlObject->xpath("/o[descendant::attrs/a[@name='EAN' and text()=".$ZmiennaEAN."]]/parent::*");
  2. foreach($oImageSection[0]->o[@price] as $oImage)

Niestety również nie działa.
Puchatek
Dziękuję za pomoc, wygląda na to, że jest ok, natomiast pozostaje jeszcze pętla foreach, w której pobierana jest cena.
Spróbowałem na 2 sposoby.
1.
  1. $oImageSection = $oSimpleXmlObject->xpath('//o/attrs/a[@name="EAN"][contains(text(),' . $ZmiennaEAN . ')]/../..');
  2. foreach($oImageSection[0]->o[@price] as $oImage)


2.
  1. $oImageSection = $oSimpleXmlObject->xpath('//o/attrs/a[@name="EAN"][contains(text(),' . $ZmiennaEAN . ')]/../../o[@price]');
  2. foreach($oImageSection[0] as $oImage)


Żaden z powyższych sposobów nie pobiera potrzebnych danych.
Neutral
Napisz, co zwraca $oImageSection.
trueblue
  1. $dom = new DOMDocument;
  2. $dom->encoding = 'UTF-8';
  3. $dom->loadXML('tu_xml');
  4.  
  5. $ZmiennaEAN = '0000000000000';
  6.  
  7. $xpath = new DOMXPath($dom);
  8. $offers = $xpath->query('//o/attrs/a[@name="EAN"][contains(text(),'.$ZmiennaEAN.')]/../..');
  9.  
  10. foreach($offers as $offer) {
  11. echo $offer->getAttribute('price');
  12. }
Puchatek
Po zastosowaniu w/w sposobu otrzymuję takie komunikaty.
Przeszukiwałem internet w celu rozwiązania tego problemu, jednak nic nie pomaga.

Kod
Warning: DOMDocument::loadXML(): Start tag expected, '<' not found in Entity, line: 1 in ...
Warning: DOMDocument::loadXML(): Start tag expected, '<' not found in Entity, line: 1 in ...

Warning: DOMDocument::loadXML(): Start tag expected, '<' not found in Entity, line: 1 in ...

Warning: DOMDocument::loadXML(): Start tag expected, '<' not found in Entity, line: 1 in ...
Tomplus
Spróbuj:

  1. $dom->load('tu_xml');
Puchatek
Niestety, ale nadal całość nie funkcjonuje.
Nie zostaje wyświetlona żadna wartość.

  1. $dom = new DOMDocument;
  2. $dom->encoding = 'UTF-8';
  3. $dom->load('link');
  4. $xpath = new DOMXPath($dom);
  5. $offers = $xpath->query('//o/attrs/a[@name="EAN"][contains(text(),'.$ZmiennaEAN.')]/../..');
  6. foreach($offers as $offer) {
  7. echo $offer->getAttribute('price');
  8. }
viking
A wartość tekstową atrybutu name z cdata dostajesz? Pamiętam że coś trzeba było włączyć do parsowania.
Neutral
link link

Chyba chodzi o
Cytat
public bool $preserveWhiteSpace = TRUE ;
, ale nie jestem pewien.

@Puchatek, zapisz plik z kodowaniem UTF-8 z BOM i sprawdź, czy pójdzie. Jeśli, nie to zapisz ten plik z kodowaniem UTF-8 bez BOM. Popróbuj tak z dwoma plikami, tym "index.php" i tym "index.xml".

BOM - Byte Order Mark.
Puchatek
Zmiany w kodowaniach również nie pomogły.
Chyba odpuszczam temat z wykorzystaniem tego XMLa, mam jeszcze możliwość pobierania tych samych danych z API tylko muszę poszerzyć swoją wiedzę na ten temat.
Dziękuję bardzo za pomoc.
trueblue
A może pokażesz ten XML? Czy dostarczasz poprawną strukturę dla metody load?
Puchatek
Struktura wygląda tak. Całego pliku XML nie mogę udostępnić ze względu na umowę.

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <offers xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0">
  3. <o id="96727" url="url" price="56.83" stock="1511" weight="0.42">
  4. <cat><![CDATA[kategoria1]]></cat>
  5. <name><![CDATA[nazwa1]]></name>
  6. <imgs>
  7. <main url="url"/>
  8. <i url="url"/>
  9. <i url="url"/>
  10. <i url="url"/>
  11. <i url="url"/>
  12. <i url="url"/>
  13. <i url="url"/>
  14. <i url="url"/>
  15. <i url="url"/>
  16. </imgs>
  17. <desc><![CDATA[opis]]></desc>
  18. <attrs>
  19. <a name="Producent"><![CDATA[producent]]></a>
  20. <a name="Kod_Producenta"><![CDATA[1111111]]></a>
  21. <a name="EAN"><![CDATA[1111111111111]]></a>
  22. </attrs>
  23. </o>
  24. <o id="92385" url="url" price="74.59" stock="2926" weight="2.8">
  25. <cat><![CDATA[kategoria2]]></cat>
  26. <name><![CDATA[nazwa2]]></name>
  27. <imgs>
  28. <main url="url"/>
  29. <i url="url"/>
  30. <i url="url"/>
  31. <i url="url"/>
  32. <i url="url"/>
  33. <i url="url"/>
  34. <i url="url"/>
  35. <i url="url"/>
  36. <i url="url"/>
  37. <i url="url"/>
  38. <i url="url"/>
  39. <i url="url"/>
  40. </imgs>
  41. <desc><![CDATA[opis]]></desc>
  42. <attrs>
  43. <a name="Producent"><![CDATA[producent]]></a>
  44. <a name="Kod_Producenta"><![CDATA[0000000]]></a>
  45. <a name="EAN"><![CDATA[2222222222222]]></a>
  46. </attrs>
  47. </o>
  48. </offers>
trueblue
Brakuje cudzysłowów. Query będzie mieć taką postać:

  1. $offers = $xpath->query('//o/attrs/a[@name="EAN"][contains(text(),"' . $ZmiennaEAN . '")]/../..');
Puchatek
Udało się, cudzysłów pomógł, serdecznie dziękuję wszystkim za pomoc smile.gif
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.