Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Poruszanie sie po strukturze XML
Indeo
post
Post #1





Grupa: Zarejestrowani
Postów: 295
Pomógł: 7
Dołączył: 26.03.2004
Skąd: Opole

Ostrzeżenie: (0%)
-----


Pewnie dla wiekszości z was zagadnienie banalne ale potrzebuję pomocy (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)

Chce załadować dane XML do jakiejś tablicy czy obiektu tak abym mógł się po niej poruszać na zasadzie
  1. <?php
  2. $tablica['element']['potomny_01']['potomny_02']...
  3. albo
  4. $tablica->element->potomny_01->potomny_02
  5. ?>

bo zwykłe wpakowanie danych przez xml_parse_into_struct zwraca strukturalnie słaby materiał (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)


Moja intencją jest po prostu wydobycie danej gałęzi i przeniesienie w inne miejsce.

Dzięki za pomoc (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 8)
Cysiaczek
post
Post #2





Grupa: Moderatorzy
Postów: 4 465
Pomógł: 137
Dołączył: 26.03.2004
Skąd: Gorzów Wlkp.




Nic prostszego - simpleXML - tworzy swój obiekt i pozwala nawigować jak Ci się żywnie podoba.

Pozdrawiam.
Go to the top of the page
+Quote Post
Indeo
post
Post #3





Grupa: Zarejestrowani
Postów: 295
Pomógł: 7
Dołączył: 26.03.2004
Skąd: Opole

Ostrzeżenie: (0%)
-----


Podoba mi sie to ale martwi mnie jedna rzecz. Prosze zobaczyć co dzieje się z tagami pliku worda:

Oryginalny XML worda zawiera:
  1. <w:sectPr >
  2.      <w:pgSz w:w="11906" w:h="16838" ></w:pgSz>
  3.      <w:pgMar w:top="1417" w:right="1417" w:bottom="1417" w:left="1417" w:header="708" w:footer="708" w:gutter="0" ></w:pgMar>
  4.      <w:cols w:space="708" ></w:cols>
  5.      <w:docGrid w:line-pitch="360" ></w:docGrid>
  6. </w:sectPr>


natomiast po przechwyceniu XML'a przez SimpleXML wygląda to tak:
  1. <sectPr>
  2.      <pgSz w="11906" h="16838"/>
  3.      <pgMar top="1417" right="1417" bottom="1417" left="1417" header="708" footer="708" gutter="0"/>
  4.      <cols space="708"/>
  5.      <docGrid line-pitch="360"/>
  6. </sectPr>


To że z pustych tagów zrobił tagi pojedyncze to spoko, ale poginęły nazwy elementów worda - znikneło wyrażenie "w:" , które jednak dla worda jest istotne.
I czemu tak się dzieje?
Go to the top of the page
+Quote Post
nospor
post
Post #4





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




simpleXML nie rozpoznaje namespaców (u ciebie to wlasnie w:).
Poszukaj jakiejs klasy opartej na DOM, moze one bedą to respektowaly, gdyz sam DOM rozpoznaje namespacy. Wiem, gdyz sam niedawno przenioslem sie na DOM spowodow wlasnie namespacow
Go to the top of the page
+Quote Post
Indeo
post
Post #5





Grupa: Zarejestrowani
Postów: 295
Pomógł: 7
Dołączył: 26.03.2004
Skąd: Opole

Ostrzeżenie: (0%)
-----


Ot i szok. Nie wiedziałem co to namespaces, a napisałem program rozwalający całą strukturę pliku XML'owego worda z 3 linijkowego krzaczora w piękna drzewiastą strukturę za pomoca samego xml_parse_into_struct i po powrotnym zrzuceniu wszystkiego z tabelki wciąż się otwiera w wordzie (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) !

Jak usłyszałem DOM aż mi ciary przeszły ... naprawde nie ma nic prostszego? Przecież na boga to tylko pliki tekstowe ze znacznikami ...
Go to the top of the page
+Quote Post
nospor
post
Post #6





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Cytat
Jak usłyszałem DOM aż mi ciary przeszły ... naprawde nie ma nic prostszego?

DOM nie jest taki zly (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)

Ale jak mowilem, przejrzyj klasy, chociazby na phpclasses.org, ktore wykorzystują DOM. Zapewne są przyjemniejsze w uzyciu a i moze namespacy zachowują.
Wynikami podziel sie w tym topicu bo sam jestem ciekaw.
Go to the top of the page
+Quote Post
Indeo
post
Post #7





Grupa: Zarejestrowani
Postów: 295
Pomógł: 7
Dołączył: 26.03.2004
Skąd: Opole

Ostrzeżenie: (0%)
-----


Już szukam. Dam znać (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)

Muszę przyznać, że jestem troche zawiedziony całym zamieszaniem wokół XML, a raczej odczuciem chaosu spowodowanym brakiem (jak dla mnie) przejrzystych ścieżek poznania aparatu jego obsługi. rzeczywiście znalazłem wiele klas opartych na DOM XML, ale za kazdym razem i tak trzeba było ingerować w logikę DOM więc bez znajomości DOm XML taka klasa mi sie nie przyda. Czytanie o DOM XML na php.net przypomina mi tą reklamę z " .... ntfs z jakims lewarowaniem" na co klient wybałusza gały ... :/ Po prostu o ile sam XML jest strukturalnie poukładany o tyle na ironię dokumentacja o narzędziach do niego jest chaotyczna.

Reasumując. Przejrzałem na php.net przykłady oparte na klasycznych funkcjach XML'owych php, i po drobnych modyfikacjach mam to czego chciałem. Mam dwie klasy - jedna odpowiada za odwzorowanie wyrażenia xml na hierarchiczną tablicę i drugą o działaniu odwrotnym tak żeby zmodyfikowaną tablice można było z powrotem zapisac jako XML.

Nie znam się specjalnie na XML. Testowałem je na plikach worda zapisanych w formacie XML i działają.


Poniżej klasy:
xml do tablicy
  1. <?php
  2. /*
  3. Klasa przetwarzająca wyrażenie XML na tablicę z zachowanie hierarchii, atrybutów
     i namespace's (przynajmniej tam gdzie używałem - xml worda)
  4. Znalazłem to na php.net, dodałem tylko opcje zachowania wielkości liter
  5. Klasa korzysta ze standardowych funkcji pbsługi XML więc nie potrzeba DOM XML it
    p.
  6.  
  7.  
  8. $objXML = new xml2Array();
  9. $arrOutput = $objXML->parse($strYourXML);
  10. print_r($arrOutput);
  11. */
  12.  
  13. class xml2Array {
  14.  var $arrOutput = array();
  15.  var $resParser;
  16.  var $strXmlData;
  17.  
  18. function parse($strInputXML) {
  19. $this->resParser = xml_parser_create ();
  20. xml_parser_set_option($this->resParser , XML_OPTION_CASE_FOLDING, 0);
  21. //xml_parser_set_option($this->resParser , XML_OPTION_SKIP_WHITE, 1);
  22. xml_set_object($this->resParser,$this);
  23. xml_set_element_handler($this->resParser, "tagOpen", "tagClosed");
  24.  
  25. xml_set_character_data_handler($this->resParser, "tagData");
  26. $this->strXmlData = xml_parse($this->resParser,$strInputXML );
  27. if(!$this->strXmlData) {
  28. die(sprintf("XML error: %s at line %d",
  29. xml_error_string(xml_get_error_code($this->resParser)),
  30. xml_get_current_line_number($this->resParser)));
  31. }
  32. xml_parser_free($this->resParser);
  33. return $this->arrOutput;
  34. }
  35.  
  36. function tagOpen($parser, $name, $attrs) {
  37. $tag=array("name"=>$name,"attrs"=>$attrs); 
  38. array_push($this->arrOutput,$tag);
  39. }
  40.  
  41. function tagData($parser, $tagData) {
  42. if(trim($tagData)) {
  43. if(isset($this->arrOutput[count($this->arrOutput)-1]['tagData'])) {
  44. $this->arrOutput[count($this->arrOutput)-1]['tagData'] .= $tagData;
  45. }else {
  46. $this->arrOutput[count($this->arrOutput)-1]['tagData'] = $tagData;
  47. }
  48. }
  49. }
  50.  
  51. function tagClosed($parser, $name) {
  52. $this->arrOutput[count($this->arrOutput)-2]['children'][] = $this->arrOutput[count($this->arrOutput)-1];
  53. array_pop($this->arrOutput);
  54. }
  55. }
  56. ?>



z tablicy do XML:

  1. <?php
  2. /*
  3. Klasa o działaniu odwrotnym do xml2Array przetwarzająca tablicę na wyrażenie XML
     z zachowanie hierarchii, atrybutów i namespace's (przynajmniej tam gdzie używałem - xml worda)
  4. Znalazłem to na php.net, ale był problem z wartościami tagów (gineły) więc trochę kod rozwinąłem
  5. Klasa korzysta ze standardowych funkcji pbsługi XML więc nie potrzeba DOM XML it
    p.
  6.  
  7.  
  8. $objXML = new Array2xml();
  9. $xmlOutput = $objXML->parse($array);//$array[0] jeśli tablica jest zwrócona przez klasę xml2Array :)
  10. print_r($xmlOutput);
  11. */
  12. class Array2xml{
  13.  
  14. function parse($root){
  15. if(count($root) > 0){
  16. $curr_name = $root['name'];
  17. $attribs = $root['attrs'];
  18. $curr_childs = $root['children'];
  19. $curr_data = $root['cdata'];
  20. $curr_tagdata=$root['tagData'];
  21. $xml .= '<'.$curr_name;
  22.  
  23. if(count($attribs) > 0){
  24. $i = 1;
  25. foreach($attribs as $key => $value){
  26. $curr_attribs .= $key.'="'.$value.'"';
  27. $i++;
  28. if($i <= count($attribs)){
  29. $curr_attribs .= ' ';
  30. }
  31. }
  32. $xml .= ' '.$curr_attribs;
  33. }
  34.  
  35. if($curr_data != ''){
  36. $xml .= '><![CDATA['.$curr_data.']]></'.$curr_name.'>';
  37. }else {
  38. if(count($curr_childs) > 0){
  39. $xml .= '>';
  40. if($curr_tagdata) $xml.=$curr_tagdata;
  41.  foreach($curr_childs as $child){
  42. $xml .= $this->parse($child);
  43. }
  44. $xml .= '</'.$curr_name.'>';
  45.  } else {
  46.  if($curr_tagdata){
  47.  $xml.='>';
  48.  $xml.=$curr_tagdata;
  49.  $xml .= '</'.$curr_name.'>';
  50. }else{
  51. $xml .= '/>';
  52. }
  53. }
  54.  }
  55.  } 
  56.  return $xml;
  57.  }
  58.  
  59.  }
  60. ?>



Mając takie wyrażenie XML:
  1. <root xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml" >
  2.      <w:ocean >spokojny
  3.            <morze >czerwone</morze>
  4.            <morze >czarne</morze>
  5.      </w:ocean>
  6.      <kontynent >
  7.            <o:kraj >Polska</o:kraj>
  8.      </kontynent>
  9. </root>


dostajemy taką tablicę:

  1. Array
  2. (
  3. [0] => Array
  4. (
  5. [name] => root
  6. [attrs] => Array
  7. (
  8. )
  9.  
  10. [children] => Array
  11. (
  12. [0] => Array
  13. (
  14. [name] => w:ocean
  15. [attrs] => Array
  16. (
  17. )
  18.  
  19. [tagData] => spokojny
  20. [children] => Array
  21. (
  22. [0] => Array
  23. (
  24. [name] => morze
  25. [attrs] => Array
  26. (
  27. )
  28.  
  29. [tagData] => czerwone
  30. )
  31.  
  32. [1] => Array
  33. (
  34. [name] => morze
  35. [attrs] => Array
  36. (
  37. )
  38.  
  39. [tagData] => czarne
  40. )
  41.  
  42. )
  43.  
  44. )
  45.  
  46. [1] => Array
  47. (
  48. [name] => kontynent
  49. [attrs] => Array
  50. (
  51. )
  52.  
  53. [children] => Array
  54. (
  55. [0] => Array
  56. (
  57. [name] => o:kraj
  58. [attrs] => Array
  59. (
  60. )
  61.  
  62. [tagData] => Polska
  63. )
  64.  
  65. )
  66.  
  67. )
  68.  
  69. )
  70.  
  71. )
  72.  
  73. )
Go to the top of the page
+Quote Post
thornag
post
Post #8





Grupa: Zarejestrowani
Postów: 504
Pomógł: 2
Dołączył: 31.03.2006
Skąd: Londyn

Ostrzeżenie: (0%)
-----


Fajne, tylko dlaczego az dwie klasy ? Mozna to zawrzec w jednej paczce i bedzie wygodniej.
Go to the top of the page
+Quote Post
Indeo
post
Post #9





Grupa: Zarejestrowani
Postów: 295
Pomógł: 7
Dołączył: 26.03.2004
Skąd: Opole

Ostrzeżenie: (0%)
-----


Oczywiście, tak jakoś wyszło (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) Własnie użyłem tych klas do załadowania do tablicy dokumentu worda w formacie XML z załączonym zdjęciem, a potem z powrotem zrzuciłem wszystko do pliku xml i działa (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) .
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 23.08.2025 - 20:48