Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [xml + php] xml_parse: jak rozdzielić?
Forum PHP.pl > Forum > XML, AJAX
criiis
Witam!
Niestety jestem początkujący i nie potrafię sobie poradzić z pewnym problem, który mnie nęka już od kilku dni. Na wstępie chciałbym zaznaczyć, że jestem po paru godzinach prób i błędów oraz szukania w manualach...
Otóż mam 2 pliki:
  1. <?xml version="1.0" encoding="ISO-8859-2"?>
  2. <offers>
  3.      <offer>
  4.            <id>1</id>
  5.            <price>1000</price>
  6.            <attributes>
  7.                  <attribute>
  8.                        <name>Gatunek</name>
  9.                                <value>Ssak</value>
  10.                  </attribute>
  11.                  <attribute>
  12.                        <name>Nazwa</name>
  13.                        <value>Słoń</value>
  14.                  </attribute>
  15.            </attributes>
  16.      </offer>
  17.      <offer>
  18.            <id>2</id>
  19.            <price>200</price>
  20.            <attributes>
  21.                  <attribute>
  22.                        <name>Gatunek</name>
  23.                        <value>Płaz</value>
  24.                  </attribute>
  25.                  <attribute>
  26.                        <name>Nazwa</name>
  27.                        <value>Ropuszka pomarańczowa</value>
  28.                  </attribute>
  29.            </attributes>
  30.       </offer>
  31. </offers>


  1. <?php
  2. class offer{
  3. var $id;
  4. var $cena;
  5. var $kod;
  6.  }
  7.  
  8.  $int = 0;
  9.  $offers = array();
  10.  $czy_offer = 0;
  11.  
  12. function tag_start($parser, $attr, $params){
  13. global $act_tag, $int, $offers, $czy_offer;
  14. if($attr == 'OFFER' && $czy_offer == 1){
  15.  die('Błąd: Niedozwolone zagnieżdżenie ofert! :]
  16. ');
  17. }elseif($attr == 'OFFER' && $czy_offer == 0){
  18.  $offers[$int] = new offer($params['ID']);
  19.  $czy_offer = 1;
  20. }
  21.  
  22. if($czy_offer == 1){
  23.  if($attr != 'PERSONALIA'){
  24. $act_tag = $attr;
  25.  }else{
  26. $offers[$int] -> imie = $params['IMIE'];  // to jest przeróbka przykładu z www - nie wiem, czemu po zahashowaniujest błąd w wyświetlaniu danych
  27. $offers[$int] -> nazwisko = $params['NAZWISKO'];  // tu tak samo
  28.  }
  29. }
  30.  }
  31.  
  32.  function tag_text($parser, $text){
  33. global $act_tag, $int, $offers, $czy_offer;
  34.  
  35. if($czy_offer == 1){
  36.  switch($act_tag){
  37. case 'ID': $offers[$int] -> id.= $text; break;
  38. case 'PRICE': $offers[$int] -> cena.= $text; break;
  39. case 'VALUE': $offers[$int] -> kod.= $text; break;
  40.  
  41.  }
  42. }
  43.  }
  44.  
  45.  function tag_end($parser, $attr){
  46. global $act_tag, $int, $czy_offer;
  47. if($attr == 'OFFER' && $czy_offer == 1){
  48.  $int++;
  49.  $czy_offer = 0;
  50. }
  51.  }
  52.  
  53.  
  54.  $parser = xml_parser_create();
  55.  
  56.  xml_set_element_handler($parser, 'tag_start', 'tag_end');
  57.  xml_set_character_data_handler($parser, 'tag_text');
  58.  
  59.  if(!($fp = fopen('plik.xml', 'r'))) {
  60. die('Nie można otworzyć podanego pliku XML!!!');
  61.  }
  62.  
  63.  while($data = fread($fp, 4096)) {
  64. if(!xml_parse($parser, $data, feof($fp))){
  65.  die(sprintf(&#092;"Błąd XML: %s w linii %d\",
  66.  xml_error_string(xml_get_error_code($_parser)),
  67.  xml_get_current_line_number($parser)));
  68.  }
  69. }
  70.  
  71.  xml_parser_free($parser); 
  72.  
  73.  foreach($offers as $offer){
  74. echo '
  75. Id: '.$offer -> id.'
  76.  
  77. Cena: '.$offer -> cena.'
  78.  
  79. Kod: '.$offer -> kod.'
  80. ';
  81.  }
  82. ?>


Wyświetla:

Id: 1
Cena: 1000
Kod: Ssak Słoń
Id: 2
Cena: 200
Kod: Płaz Ropuszka pomarańczowa

Moim problemem jest wyświetlanie tylko pierwszej cześci "Kodu" - Ssak, Płaz...
Chciałbym, żeby się wyświetlało:
Id: 1
Cena: 1000
Kod: Ssak
Id: 2
Cena: 200
Kod: Płaz


Czy ktoś jest mi w stanie pomóc?
paziek
  1. <?php
  2. $doc = new DOMDocument;
  3. //nie potrzeba nam tych spacji
  4. $doc->preserveWhiteSpace = false;
  5.  
  6. $doc->load('file.xml');
  7.  
  8. $xpath = new DOMXPath($doc);
  9.  
  10. //wyciągamy wszystkie oferty z XMLa i wrzucamy do zmiennej $offers jako lista
  11. $offers = $xpath->query('offers/offer', $doc);
  12.  
  13. //pętla na liście ofert
  14. foreach ($offers as $offer) {
  15. //wykonujemy zapytanie XPath relatywnie do oferty!
  16. $id = $xpath->query('id', $offer);
  17. $price = $xpath->query('price', $offer);
  18. //wyciągamy pierwszy atrybut z listy atrybutów (w XPath jest to [1], w DOM miałbyś [0] - nie pomyl!
  19. $attr1 = $xpath->query('attributes/attribute[1]/value', $offer);
  20. echo 'ID: '.$id->item(0)->nodeValue;
  21. echo '<br />';
  22. echo 'PRICE: '.$price->item(0)->nodeValue;
  23. echo '<br />';
  24. echo 'ATTR1: '.$attr1->item(0)->nodeValue;
  25. echo '<br />';echo '<br />';
  26. }
  27. ?>


Do poczytania:
XPath w PHP http://pl2.php.net/manual/pl/domxpath.query.php
Składnia XPath http://www.w3schools.com/XPath/xpath_syntax.asp


XPath jest BARDZO prosty. Może się na początku wydawać dosyć dziwny, ale bardzo ułatwia życie, a jak go już poznasz - to już tylko XPathem będziesz 'latał' po XMLach ;-)

ps. Opuściłeś tam końcowy tag w swoim pliku XML, nie wiem czy tylko tutaj przy wklejaniu, czy tak masz w pliku - jeśli to drugie, to popraw go.
criiis
Dziękuję za odpowiedź. Naprawdę bardzo mi pomogła, ale mam jeszcze tylko 2 małe pytania:
* jaka może być przyczynna złego wyświetlania słowa "Płaz"? Obydwa pliki są zapisane w kodowaniu ISO-8859-2
ATTR1: P�az
* czy zamiast odnośnika do pliku xml
  1. <?php
  2. doc->load('file.xml');
  3. ?>

mamy możliwość linkowania do konkretnej strony php, która generuje XML?

Ps. Poprawiłem zamknięcie w xml'u. Błąd przy kopiowaniu.
paziek
Musisz przekonwertować z utf-8 na iso-8859-2. Trudno mi powiedzieć dlaczego..
  1. <?php
  2. echo 'ATTR1: '.iconv('utf-8','iso-8859-2',$attr1->item(0)->nodeValue);
  3. ?>


Co do drugiego pytania, to zakładam, że wiesz jak pobrać z tej konkretnej strony treść XMLa i wrzucić ją do zmiennej, wtedy zamiast
  1. <?php
  2. $doc->load('file.xml');
  3. ?>

używasz
  1. <?php
  2. $doc->loadXML($zawartośćTejStrony);
  3. ?>
criiis
Naprawdę brak mi słów... Dzięki!
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.