Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: namespaces,simplexml_load_file();
Forum PHP.pl > Forum > XML, AJAX > XML
morrison
wiec mam taki format pliku test.xml:

  1. <?xml version="1.0" encoding="ISO-8859-2"?>
  2. <bibtex:entry bibtex:id="11/2002">
  3. <bibtex:inproceedings>
  4. <bibtex:author>Kubus</bibtex:author>
  5. <bibtex:title>architecture</bibtex:title>
  6. <bibtex:booktitle>Optical Internet</bibtex:booktitle>
  7. <bibtex:address>Poznan</bibtex:address>
  8. <bibtex:year>2002</bibtex:year>
  9. <bibtex:publisher>wyd</bibtex:publisher>
  10. <bibtex:pages>221-233</bibtex:pages>
  11. </bibtex:inproceedings>
  12. </bibtex:entry>
  13. <bibtex:entry bibtex:id="12/2002">
  14. <bibtex:inproceedings>
  15. <bibtex:author>Mazur</bibtex:author>
  16. <bibtex:title>klaster</bibtex:title>
  17. <bibtex:booktitle>Aprilll</bibtex:booktitle>
  18. <bibtex:address>Poznan</bibtex:address>
  19. <bibtex:year>2002</bibtex:year>
  20. <bibtex:publisher>Instytut</bibtex:publisher>
  21. <bibtex:pages>113-122</bibtex:pages>
  22. </bibtex:inproceedings>
  23. </bibtex:entry>


chodzi mi o to jak zdefiniowac przestrzen nazw dla przypadku: <bibtex:entry bibtex:id="11/2002"> ?

Chce za pomoca funkcji simplexml_load_file(); uzyskac wszystkie dane z pliku xml i oczywiscie miec mozliwosc operowania na nich. Probowalem czegos takiego:

  1. <?php
  2. $entries = simplexml_load_file('test.xml');
  3. foreach ($entries->bibtex->inproceedings as $entry) {
  4. printf("%sn", $entry->author);
  5. }
  6. ?>


I to i inne proby nie dzialaja, czy ktos potrafi mi pomoc??

pozdr;)
aleksander
do XMLa służy tag [xml]
prosze poprawic
Sh4dow
jesli chodzi o uzywanie namespace w xml to poprawiony kod xml wyglada tak
  1. <?xml version="1.0" encoding="ISO-8859-2"?>
  2. <entry>
  3. <bibtex:entry xmlns:bibtex="11/2002">
  4. <bibtex:inproceedings>
  5. <bibtex:author>Kubus</bibtex:author>
  6. <bibtex:title>architecture</bibtex:title>
  7. <bibtex:booktitle>Optical Internet</bibtex:booktitle>
  8. <bibtex:address>Poznan</bibtex:address>
  9. <bibtex:year>2002</bibtex:year>
  10. <bibtex:publisher>wyd</bibtex:publisher>
  11. <bibtex:pages>221-233</bibtex:pages>
  12. </bibtex:inproceedings>
  13. </bibtex:entry>
  14. <bibtex:entry xmlns:bibtex="12/2002">
  15. <bibtex:inproceedings>
  16. <bibtex:author>Mazur</bibtex:author>
  17. <bibtex:title>klaster</bibtex:title>
  18. <bibtex:booktitle>Aprilll</bibtex:booktitle>
  19. <bibtex:address>Poznan</bibtex:address>
  20. <bibtex:year>2002</bibtex:year>
  21. <bibtex:publisher>Instytut</bibtex:publisher>
  22. <bibtex:pages>113-122</bibtex:pages>
  23. </bibtex:inproceedings>
  24. </bibtex:entry>
  25. </entry>


Dodanie enty jest wymagane poniewaz xml powinien miec oczywiscie swoj root w drzewie a tutaj jest tym <entry> ... </entry> a zamiast twojego
  1. <bibtex:entry bibtex:id="11/2002">

powinna byc jakas definicja namespace dla xml czyli przeksztalcamy to na
  1. <bibtex:entry xmlns:id="11/2002">

lub
  1. <bibtex:entry xmlns:bibtex="11/2002">


U mnie bynajmniej dziala Rkingsmiley.png
morrison
wiec jesli chodzi o skladnie pliku XML to mam ja powiedzmy narzucona i nie wiem jeszcze czy bedzie mogla miec ona taka postac jak zaproponowales. Ale biorac pod uwage ze moze byc, probowalem Twojej rady, jednak bez rezultatow. Jesli twierdzisz ze Ci to dziala to prosze zamiesc kod php, ktory wyswietla jakies dane z pliku XML za pomoca omawianej funkcji.
Ja w swoich probach uzyskiwalem: albo pusty bialy ekran, albo blad:
Warning: Invalid argument supplied for foreach() in example.php on line 3

bede wdzieczny za pomoc
pozdr;)
Sh4dow
To jest zywcem z manuala php
  1. <?php
  2. // The file test.xml contains an XML document with a root element
  3. // and at least an element /[root]/title.
  4.  
  5. if (file_exists('test.xml')) {
  6.  $xml = simplexml_load_file('test.xml');
  7.  
  8.  var_dump($xml);
  9. } else {
  10.  exit('Failed to open test.xml.');
  11. }
  12. ?>


to jest plik test.xml z moimi poprawkami
  1. <?xml version="1.0" encoding="ISO-8859-2"?>
  2. <entry>
  3. <bibtex:entry xmlns:bibtex="11/2002">
  4. <bibtex:inproceedings>
  5. <bibtex:author>Kubus</bibtex:author>
  6. <bibtex:title>architecture</bibtex:title>
  7. <bibtex:booktitle>Optical Internet</bibtex:booktitle>
  8. <bibtex:address>Poznan</bibtex:address>
  9. <bibtex:year>2002</bibtex:year>
  10. <bibtex:publisher>wyd</bibtex:publisher>
  11. <bibtex:pages>221-233</bibtex:pages>
  12. </bibtex:inproceedings>
  13. </bibtex:entry>
  14. <bibtex:entry xmlns:bibtex="12/2002">
  15. <bibtex:inproceedings>
  16. <bibtex:author>Mazur</bibtex:author>
  17. <bibtex:title>klaster</bibtex:title>
  18. <bibtex:booktitle>Aprilll</bibtex:booktitle>
  19. <bibtex:address>Poznan</bibtex:address>
  20. <bibtex:year>2002</bibtex:year>
  21. <bibtex:publisher>Instytut</bibtex:publisher>
  22. <bibtex:pages>113-122</bibtex:pages>
  23. </bibtex:inproceedings>
  24. </bibtex:entry>
  25. </entry>


a tak wyglada wynik u mnie

Kod
object(SimpleXMLElement)[1]
  public 'entry' =>
    array
      0 =>
        object(SimpleXMLElement)[2]
          public 'inproceedings' =>
            object(SimpleXMLElement)[4]
              public 'author' => 'Kubus'
              public 'title' => 'architecture'
              public 'booktitle' => 'Optical Internet'
              public 'address' => 'Poznan'
              public 'year' => '2002'
              public 'publisher' => 'wyd'
              public 'pages' => '221-233'
      1 =>
        object(SimpleXMLElement)[3]
          public 'inproceedings' =>
            object(SimpleXMLElement)[5]
              public 'author' => 'Mazur'
              public 'title' => 'klaster'
              public 'booktitle' => 'Aprilll'
              public 'address' => 'Poznan'
              public 'year' => '2002'
              public 'publisher' => 'Instytut'
              public 'pages' => '113-122'


jesli skozystalbym z twojego pliku xml otrzymuje nastepujace bledy

Cytat
Warning: test.xml:2: namespace error : Namespace prefix bibtex for id on entry is not defined in D:\backup\test.php on line 6


Moze to cos pomoze. Z bledu wynika ze musialbys zdefinipowac prefix dla namespace, ale niestety nie do konca kojaze o co tu moze chodzic.

Powodzenia dalej. W razie pytan pisz smile.gif

Chyba zrobie sobie specjalizacje w xmlu Rkingsmiley.png
bela
Zdefiniować czyli zawrzeć definicji w <entry>
Czyli coś mniej więcej takiego <entry xmlns:bibtex="http://adres/specyfikacji">

Pisane z głowy, do sprawdzenia.
Sh4dow
No patrz o tym zapomnialem, a w robocie mialem ostatnio podobnie.

teraz to wygada to tak
  1. <?xml version="1.0" encoding="ISO-8859-2"?>
  2. <entry xmlns:bibtex="http://adres/specyfikacji"> <!-- <<< DODANO !! -->
  3. <bibtex:entry bibtex:id="11/2002">
  4. <bibtex:inproceedings>
  5. <bibtex:author>Kubus</bibtex:author>
  6. <bibtex:title>architecture</bibtex:title>
  7. <bibtex:booktitle>Optical Internet</bibtex:booktitle>
  8. <bibtex:address>Poznan</bibtex:address>
  9. <bibtex:year>2002</bibtex:year>
  10. <bibtex:publisher>wyd</bibtex:publisher>
  11. <bibtex:pages>221-233</bibtex:pages>
  12. </bibtex:inproceedings>
  13. </bibtex:entry>
  14. <bibtex:entry bibtex:id="12/2002">
  15. <bibtex:inproceedings>
  16. <bibtex:author>Mazur</bibtex:author>
  17. <bibtex:title>klaster</bibtex:title>
  18. <bibtex:booktitle>Aprilll</bibtex:booktitle>
  19. <bibtex:address>Poznan</bibtex:address>
  20. <bibtex:year>2002</bibtex:year>
  21. <bibtex:publisher>Instytut</bibtex:publisher>
  22. <bibtex:pages>113-122</bibtex:pages>
  23. </bibtex:inproceedings>
  24. </bibtex:entry>  <!-- <<< DODANO !! -->
  25. </entry>


Dziala, ale tak czy tak musisz modyfikowac otrzymywany plik.
morrison
dzieki za podpowiedzi:) dzialac dziala, nawet tak jak napisalem w prosbie-wybiera wszystkie dane. Ale dokladniej to chce uzyskac cos takiego ze: mam w pliku xml powiedzmy 1000 pozycji "inproceedings" i innych i uzytkownik w systemie wybiera sobie np, ze chce zobaczyc 545tą pozycję z pliku. Wiec wowczas musze wykonac takie "zapytanie" by uzyskac wlasnie ta pozycje z pliku. I to jest moj glowny problem: jak wybrac z tego pliku wlasnie okreslona pozycje, albo np wybrane dwa atrybuty z niej: author i title? w pierwszej mojej wiadomosci w tym temacie napisalem petle foreach do wypisania authora, ale to nie dziala. potrzebuje rozwiazanie ktore bedzie w latwy sposob wydostawac te dane z pliku(sama wartosc danego pola, bez zadnych nawiasow i cudzyslowow).

pozdr
dr_bonzo
Simplexml a potem zastosuj na tym xpatha.
Cytat
SimpleXMLElement->xpath --  Runs Xpath query on XML data
Description
array SimpleXMLElement->xpath ( string path )
The xpath method searches the SimpleXML node for children matching the Xpath path. It always returns an array of SimpleXMLElement objects.
--Manual
morrison
niestety zaimplementowac cos jest trudniej niz wymyslic koncepcje. Juz probowalem xpath'a wczesniej(wielu rzeczy probowalem, mam nawet klasy ktore pieknie wypisuja zawartosc ktoregokolwiek z elementow-ale problem zaczyna sie gdy w pliku xml pojawiaja sie przestrzenie nazw, wtedy kazde z rozwiazan zawodzi:(

oto co probowalem:

1 rozwiazanie)
  1. <?php
  2.  
  3. if (file_exists('next4.xml')) {
  4.  $xml = simplexml_load_file('next4.xml');
  5.  
  6. $result = $xml->xpath('/entry/inproceedings/title');
  7. while(list( , $node) = each($result)) {
  8.  echo 'wynik: ',$node,"n";
  9. }
  10.  
  11. } else {
  12.  exit('Failed to open test.xml.');
  13. }
  14.  
  15. ?>


plik xml
  1. <?xml version="1.0" encoding="ISO-8859-2"?>
  2. <entry xmlns:bibtex="http://adres/specyfikacji">
  3. <bibtex:entry bibtex:id="11/2002">
  4. <bibtex:inproceedings>
  5. <bibtex:author>Kubus</bibtex:author>
  6. <bibtex:title>architecture</bibtex:title>
  7. <bibtex:booktitle>Optical Internet</bibtex:booktitle>
  8. <bibtex:address>Poznan</bibtex:address>
  9. <bibtex:year>2002</bibtex:year>
  10. <bibtex:publisher>wyd</bibtex:publisher>
  11. <bibtex:pages>221-233</bibtex:pages>
  12. </bibtex:inproceedings>
  13. </bibtex:entry>
  14. <bibtex:entry bibtex:id="12/2002">
  15. <bibtex:inproceedings>
  16. <bibtex:author>Mazur</bibtex:author>
  17. <bibtex:title>klaster</bibtex:title>
  18. <bibtex:booktitle>Aprilll</bibtex:booktitle>
  19. <bibtex:address>Poznan</bibtex:address>
  20. <bibtex:year>2002</bibtex:year>
  21. <bibtex:publisher>Instytut</bibtex:publisher>
  22. <bibtex:pages>113-122</bibtex:pages>
  23. </bibtex:inproceedings>
  24. </bibtex:entry>
  25. </entry>


wynik:

Warning: Variable passed to each() is not an array or object in /home/pawel/public_html/next4.php on line 7

2 rozwiazanie)

  1. <?php
  2.  
  3. class XML_element extends SimpleXMLElement {
  4.  
  5.  function attributes() {
  6.  return new EFXMLAttributes(parent::attributes());
  7.  }
  8. }
  9.  
  10. class EFXMLAttributes {
  11.  private $attributes;
  12.  
  13.  function __construct($attributes) {
  14.  $this->attributes = $attributes;
  15.  }
  16.  
  17.  function __get($name) {
  18.  if (isset($this->attributes[$name])) {
  19.  return $this->attributes[$name];
  20.  } else {
  21.  return false;
  22.  }
  23.  }
  24. }
  25.  
  26. if (file_exists('next3.xml')) {
  27.  $tst = new XML_element(file_get_contents('next3.xml'));
  28.  
  29.  echo $tst->entry->inproceedings[1]->author;
  30.  
  31. } else {
  32.  exit('Failed');
  33. }
  34.  
  35. ?>


niestety w tym wypadku funkcja file_get_contents() nie akceptuje znaku ":" wymaganego przez przestrzenie nazw w xml:(

czy ktos potrafi napisac kod ktory wybierze dowolnie wybrany atrybut z pliku xml??

pozdr:)
morrison
nie rozumiem. wedlu mnie kod:
  1. <?php
  2. $xml = <<<EOD
  3. <?xml version="1.0" ?>
  4. <chapter xmlns:xi="http://www.w3.org/2001/XInclude">
  5. <title>Books of the other guy..</title>
  6. <para>
  7.  <xi:include href="book.xml">
  8.   <xi:fallback>
  9.    <error>xinclude: book.xml not found</error>
  10.   </xi:fallback>
  11.  </xi:include>
  12.  <include>
  13.   This is another namespace
  14.  </include>
  15. </para>
  16. </chapter>
  17. EOD;$dom = new DOMDocument;
  18. // load the XML string defined above
  19. $dom->loadXML($xml);
  20. foreach ($dom->getElementsByTagNameNS('http://www.w3.org/2001/XInclude', '*') as $element) {
  21.  echo 'local name: ', $element->localName, ', prefix: ', $element->prefix, "n";
  22. }
  23. ?>


nie jest pomocny w moim przypadku.
Oto wynik dzialania:
Kod
local name: include, prefix: xi
local name: fallback, prefix: xi


tak wiec mozliwe jest uzyskanie jedynie nazwy atrybutu danego elementu(znacznika) a nie wartosc znacznika XML. Tak wiec jesli ktos wie jak rozwiazac moj problem to prosze raz jeszcze o pomoc. To na pewno musi dac sie zrobic jakos.....

pozdr
bela
Spójrz wreszcie do manuala i zobacz jakie atrybuty ma ten obiekt.

hint.
$element->nodeValue;
morrison
spojrzałem do manuala i próbowałem zastosować przykład - bez pozytywnych rezultatów, tymbardziej, ze musze miec caly plik zaladowany do zmiennej, a nie string.
Ale czesciowo rozwiazalem swoj problem dzieki Xpath. Jednakze do tego celu musialem uzyc odpowiedniego zapytania aby uzyskac dane czyli np:

  1. <?php
  2.  
  3. $xml = simplexml_load_file('next4.xml');
  4. $result = $xml->xpath('//*[contains(name(), "year")]');
  5.  
  6. echo $result[0]"<br />";  //jedna mozliwosc
  7.  
  8. while(list( , $node) = each($result)) {  //druga mozliwosc
  9.  echo '<br />',$node,"n";
  10. }
  11.  
  12. ?>


Kluczem wlasnie do wybrania danych jest skonstruowanie odpowiedniego zapytania(mozna to porownac do bazy danych, a Xpath jest jak jezyk SQL)
wiecej na stronie: http://www.w3.org/TR/xpath

Ale jesli ktos z Was znajdzie inny sposob wybrania danych to chetnie go poznam smile.gif

pozdr
splatch
Nie jestem pewien, bo problem jest dość długi, ale możesz spróbować
  1. <?php
  2. $elements = $simplexml->xpath("/entry/*/[@name='year']");
  3. ?>


To się dopasuje do
  1. <entry>
  2.    <test name="year">blabla</test>
  3. </entry>
morrison
Wraz z rozwiązaniem, które znalazłem nasunął się kolejny problem(to chyba dobrze:)
Więc w tym kodzie:

  1. <?php
  2.  
  3. $result = $xml->xpath('//*[contains(name(), "year")]');
  4.  
  5. ?>

wybieram wszystkie elementy, które zawierają w nazwie string:"year".
O ile w wyszukiwanym pliku znajdują się elementy o takiej nazwie wówczas wszystkie ich wartości zostają wybrane. Ale jeśli w pliku analizowanym nie ma takiego elementu wówczas zostają wypisane błędy na ekran. Jak obejść ten problem? Generalnie użytkownik w moim systemie ma możliwość wybrania jednego z pól i te pola zostają wypisane z całego pliku, a właśnie jeśli wybierze pole którego nie ma w danym pliku to wyrzucane są błędy sad.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.