Parsing XML podataka. Parsiranje XML podataka Instanciranje parsera


Autor: Arseny Kapoulkine
Datum objave: 21. septembar 2012
Prijevod: A. Panin
Datum prevoda: 10. novembar 2013

Uvod

XML je standardizovani jezik za označavanje koji ima skup pravila za kodiranje hijerarhijski strukturiranih dokumenata na način čitljiv za ljude. tekstualni format. XML standard je postao široko rasprostranjen i koristi se za generisanje i veoma kompaktnih jednostavnih dokumenata (kao što su SOAP zahtevi) i višegigabajtnih dokumenata (koje koristi projekat OpenStreetMap) sa složenim zavisnostima podataka (COLLADA). Za obradu XML dokumenata, korisnicima je obično potrebna posebna biblioteka: ona mora implementirati parser XML dokumenata koji pretvara dokument iz tekstualnog dokumenta u internu reprezentaciju. XML standard je kompromis u pogledu brzine raščlanjivanja, čitljivosti korisnika i složenosti koda za raščlanjivanje – stoga, posedovanje brzog sistema za raščlanjivanje XML dokumenata može uticati na preferirani izbor XML-a kao formata za skladištenje podataka aplikacije.

Ovo poglavlje opisuje različite tehnike koje imaju za cilj poboljšanje performansi opisanog sistema za raščlanjivanje i omogućavaju autoru da razvije izuzetno produktivan sistem za raščlanjivanje koristeći C++ programski jezik: pugixml. Iako su ove tehnike korištene za XML sistem raščlanjivanja dokumenata, većina ih se može primijeniti na sisteme za raščlanjivanje dokumenata drugih formata ili čak u potpuno nepovezanim softverskim komponentama (na primjer, algoritmi za upravljanje memorijom se široko koriste u nepovezanim sistemima za raščlanjivanje tekstualni dokumenti oblasti).

Budući da postoji nekoliko široko različitih pristupa raščlanjivanju XML dokumenata, a sistem raščlanjivanja mora izvršiti dodatne korake kojih čak ni oni koji imaju iskustva s XML dokumentima nisu svjesni, važno je prvo opisati zadatak prije nego što se uđe u detalje o detaljima implementacije.

Modeli sistema za analizu XML-a

Svaki od razni modeli Sistemi za analizu XML dokumenata su optimalni u određenim situacijama i svaki od ovih modela ima svoje performanse i parametre potrošnje memorije. Sljedeći modeli su najčešće korišteni:

  • Kada koristi SAX-bazirane sisteme za raščlanjivanje (Simple API za XML), korisnik prima na svojoj lokaciji softverska komponenta, koji očekuje tok podataka dokumenta kao ulaz i pruža nekoliko funkcija povratnog poziva kao što su "open tag", "close tag", "character inside tag". Sistem za raščlanjivanje koristi funkcije povratnog poziva dok obrađuje podatke dokumenta. Kontekst potreban za raščlanjivanje ograničen je dubinom stabla trenutnog elementa, što implicira značajno smanjenje zahtjeva za memorijom. Ovaj tip sistema za raščlanjivanje može se koristiti za obradu strimovanih dokumenata kada je istovremeno dostupan samo dio dokumenta.
  • Povlačenje raščlanjivanja je slično raščlanjivanju zasnovanom na SAX-u u smislu samog procesa - jedan element dokumenta se obrađuje u isto vrijeme, ali je način upravljanja procesom raščlanjivanja promijenjen: u sistemu raščlanjivanja zasnovanom na SAX-u, proces raščlanjivanja kontroliše sam sistem koristeći funkcije povratnog poziva, dok dok je u analizi povlačenja, korisnik kontrolira proces raščlanjivanja koristeći objekt sličan iteratoru.
  • Kada koristi DOM-bazirane sisteme za raščlanjivanje (Document Object Model), korisnik prosljeđuje sistemu za raščlanjivanje kompletan dokument u obliku međuspremnika ili toka tekstualnih podataka, na osnovu kojih sistem za raščlanjivanje generiše u memoriji objektni prikaz cjelokupnog stablo elemenata dokumenta, koristeći zasebne objekte za svaki određeni element ili XML atribut, kao i skup važećih operacija (na primjer, "dobiti sve podređeni elementi ovaj čvor"). Pugxml biblioteka koristi ovaj model.

Izbor modela sistema za raščlanjivanje obično zavisi od veličine dokumenta i njegove strukture. Budući da pugixml analizira na osnovu DOM-a, efikasan je za dokumente koji:

  • toliko su male veličine da mogu u potpunosti stati u memoriju,
  • imaju složenu strukturu sa vezama između čvorova koje treba preći, ili
  • zahtijevaju složene transformacije dokumenata.

Arhitektonska rješenja u pugixml

Tokom razvoja pugixml biblioteke, veliki dio fokusa bio je na problemu kreiranja DOM reprezentacije, budući da su, iako su brzi i lagani sistemi za raščlanjivanje zasnovani na SAX-u (kao što je Expat) bili dostupni, svi DOM bazirani XML sistemi za raščlanjivanje bili dostupni za proizvodnju upotreba u vrijeme kada je pugixml kreiran (2006.) nisu bili previše lagani ili nisu prebrzi. Na osnovu ovoga, glavni cilj procesa razvoja puixml-a je stvaranje vrlo brze, lagane biblioteke za obavljanje DOM-bazirane manipulacije XML dokumentima.


Objava ovog članka je dozvoljena samo uz vezu na web stranicu autora članka

U ovom članku ću pokazati primjer kako raščlaniti veliku XML datoteku. Ako vaš server (hosting) ne zabranjuje povećanje vremena rada skripte, onda možete analizirati XML datoteku od najmanje gigabajta; ja sam lično analizirao samo datoteke iz ozona teške 450 megabajta.

Kada analizirate velike XML datoteke, javljaju se dva problema:
1. Nema dovoljno memorije.
2. Nema dovoljno vremena da se skripta pokrene.

Drugi problem sa vremenom se može riješiti ako ga server ne zabrani.
Ali problem s memorijom je teško riješiti, čak i ako govorimo o vlastitom serveru, onda premještanje datoteka od 500 megabajta nije baš lako, a jednostavno nije moguće povećati memoriju na hostingu i VDS-u.

PHP ima nekoliko ugrađenih opcija za obradu XML-a - SimpleXML, DOM, SAX.
Sve ove opcije su detaljno opisane u mnogim člancima s primjerima, ali svi primjeri pokazuju rad s punim XML dokumentom.

Evo jednog primjera iz kojeg dobijamo objekt XML fajl

Sada možete obraditi ovaj objekat, ALI...
Kao što možete vidjeti, cijeli XML fajl se čita u memoriju, a zatim se sve analizira u objekt.
Odnosno, svi podaci idu u memoriju i ako nema dovoljno dodijeljene memorije, skripta se zaustavlja.

Ova opcija nije prikladna za obradu velikih datoteka; morate čitati datoteku red po red i obraditi ove podatke jedan po jedan.
U ovom slučaju, provjera valjanosti se također provodi kako se podaci obrađuju, tako da morate biti u mogućnosti da se vratite, na primjer, izbrišete sve podatke unesene u bazu podataka u slučaju nevažeće XML datoteke ili izvršite dva prolaza kroz datoteku, prvo pročitajte radi valjanosti, a zatim pročitajte za obradu podataka.

Evo teorijskog primjera raščlanjivanja velike XML datoteke.
Ova skripta čita jedan po jedan znak iz datoteke, prikuplja ove podatke u blokove i šalje ih XML parseru.
Ovaj pristup u potpunosti rješava problem s memorijom i ne uzrokuje opterećenje, ali s vremenom pogoršava problem. Kako pokušati riješiti problem s vremenom, pročitajte u nastavku.

Funkcija webi_xml ($file)
{

########
### data funkcija

{
print $data ;
}
############################################



{
print $name ;
print_r($attrs);
}


## funkcija zatvaranja oznake
funkcija endElement ($parser, $name)
{
print $name ;
}
############################################

($xml_parser, "podaci");

// otvorite datoteku
$fp = fopen($file, "r");

$perviy_vxod = 1; $data = "" ;



{

$simvol = fgetc ($fp); $data .= $simvol ;


if($simvol != ">" ) (nastavi;)


eho"

break;
}

$data = "" ;
}
fclose($fp);

Webi_xml("1.xml");

?>

U ovom primjeru, sve sam stavio u jednu funkciju webi_xml() i na samom dnu možete vidjeti njen poziv.
Sama skripta se sastoji od tri glavne funkcije:
1. Funkcija koja hvata otvaranje oznake startElement().
2. Funkcija koja hvata završnu oznaku endElement().
3. I funkcija primanja podataka data() .

Pretpostavimo da je sadržaj datoteke 1.xml recept



< title >Jednostavan hleb
< ingredient amount = "3" unit = "стакан" >Brašno
< ingredient amount = "0.25" unit = "грамм" >Kvasac
< ingredient amount = "1.5" unit = "стакан" >Toplu vodu
< ingredient amount = "1" unit = "чайная ложка" >Sol
< instructions >
< step > Pomiješajte sve sastojke i dobro izmiješajte.
< step > Pokrijte krpom i ostavite jedan sat u toploj prostoriji..
< step > Ponovo mesiti, stavite na pleh i stavite u rernu.
< step > Posjetite web stranicu


Sve počinjemo pozivanjem opće funkcije webi_xml ("1.xml");
Zatim, parser se pokreće u ovoj funkciji i svi nazivi oznaka se pretvaraju u velika slova tako da sve oznake imaju ista velika slova.

$xml_parser = xml_parser_create();
xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, istina);

Sada ukazujemo koje funkcije će raditi na hvatanju otvaranja oznake, zatvaranja i obrade podataka

xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "podaci");

Sljedeće dolazi otkriće specificirani fajl, iterira kroz datoteku jedan po jedan znak i svaki znak se dodaje varijabli stringa sve dok se znak ne pronađe > .
Ako je ovo prvi pristup datoteci, usput će se izbrisati sve što je nepotrebno na početku datoteke, sve što dolazi prije , ovo je oznaka s kojom bi XML trebao početi.
Po prvi put, string varijabla će sadržavati string

I pošaljite ga rastavljaču
xml_parse ($xml_parser, $data, feof ($fp));
Nakon obrade podataka, varijabla niza se resetuje i prikupljanje podataka u niz počinje ponovo i niz se formira po drugi put

Na trećem
</b><br>na četvrtom <br><b>Jednostavan hleb

Imajte na umu da se varijabla string uvijek formira iz završene oznake > i nije potrebno poslati provalniku otvorenu i zatvorenu oznaku sa podacima, na primjer
Jednostavan hleb
Važno je da ovaj rukovalac primi cijelu neprekinutu oznaku, barem jednu otvorenu oznaku, a u sljedećem koraku i zatvorenu oznaku, ili odmah primi 1000 redova datoteke, nije bitno, glavno je da oznaka ne lomi se npr

le>Običan hleb
Na ovaj način je nemoguće poslati podatke rukovaocu, jer je tag pocijepan.
Možete smisliti vlastiti način slanja podataka rukovaocu, na primjer, prikupiti 1 megabajt podataka i poslati ih rukovaocu da povećate brzinu, samo pazite da su oznake uvijek dovršene i da se podaci mogu pocijepati
Jednostavno</b><br><b>hljeb

Dakle, u dijelovima po želji možete slati veliki fajl rukovaocu.

Pogledajmo sada kako se ovi podaci obrađuju i kako do njih doći.

Počnimo s funkcijom otvaranja oznaka startElement ($parser, $name, $attrs)
Pretpostavimo da je obrada stigla do linije
< ingredient amount = "3" unit = "стакан" >Brašno
Tada će unutar funkcije varijabla $name biti jednaka sastojak odnosno naziv otvorene oznake (još nije došlo do zatvaranja oznake).
Također u ovom slučaju, niz atributa ove oznake $attrs će biti dostupan, koji će sadržavati podatke količina = "3" i jedinica = "staklo".

Nakon toga, podaci otvorene oznake su obrađeni od strane funkcije podaci ($parser, $data)
Varijabla $data će sadržavati sve što je između otvaranja i zatvaranja oznake, u našem slučaju ovo je tekst Muka

I obrada našeg stringa od strane funkcije se završava endElement ($parser, $name)
Ovo je naziv zatvorene oznake, u našem slučaju $name će biti jednako sastojak

I nakon toga se sve opet vrtjelo u krug.

Gornji primjer samo demonstrira princip XML obrade, ali za stvarnu primjenu ga je potrebno modificirati.
Obično morate raščlaniti veliki XML da biste unijeli podatke u bazu podataka, a da biste pravilno obrađivali podatke morate znati kojoj otvorenoj oznaci podaci pripadaju, koji nivo ugniježđenja oznaka i koje su oznake otvorene u gornjoj hijerarhiji. Sa ovim informacijama možete ispravno obraditi datoteku bez ikakvih problema.
Da biste to učinili, morate uvesti nekoliko globalnih varijabli koje će prikupljati informacije o otvorenim oznakama, ugniježđenju i podacima.
Evo primjera koji možete koristiti

Funkcija webi_xml ($file)
{
globalni $webi_depth; // brojač za praćenje dubine gniježđenja
$webi_depth = 0;
globalno $webi_tag_open ; // će sadržavati niz otvorenih in ovog trenutka oznake
$webi_tag_open = niz();
globalni $webi_data_temp ; // ovaj niz će sadržavati podatke jedne oznake

####################################################
### data funkcija
podaci funkcije ($parser, $data)
{
globalni $webi_depth;
globalno $webi_tag_open ;
globalni $webi_data_temp ;
// dodaje podatke u niz koji ukazuje na ugniježđenje i trenutno otvorenu oznaku
$webi_data_temp [ $webi_depth ][ $webi_tag_open [ $webi_depth ]][ "podaci" ].= $podaci ;
}
############################################

####################################################
### funkcija otvaranja oznake
funkcija startElement ($parser, $name, $attrs)
{
globalni $webi_depth;
globalno $webi_tag_open ;
globalni $webi_data_temp ;

// ako nivo gniježđenja više nije nula, tada je jedna oznaka već otvorena
// a podaci iz njega su već u nizu, možete ih obraditi
if ($webi_depth)
{




" ;

print "
" ;
print_r($webi_tag_open); // niz otvorenih oznaka
print "


" ;

// nakon obrade podataka, izbrišite ih da biste oslobodili memoriju
unset($GLOBALS [ "webi_data_temp" ][ $webi_depth ]);
}

// sada se otvara sljedeća oznaka i daljnja obrada će se dogoditi u sljedećem koraku
$webi_depth++; // povećanje gniježđenja

$webi_tag_open [ $webi_depth ]= $name; // dodajemo otvorenu oznaku u niz informacija
$webi_data_temp [ $webi_depth ][ $name ][ "attrs" ]= $attrs ; // sada dodaj atribute oznake

}
###############################################

#################################################
## funkcija zatvaranja oznake
funkcija endElement ($parser, $name) (
globalni $webi_depth;
globalno $webi_tag_open ;
globalni $webi_data_temp ;

// obrada podataka počinje ovdje, na primjer dodavanje u bazu podataka, spremanje u datoteku, itd.
// $webi_tag_open sadrži lanac otvorenih oznaka prema nivou ugniježđenja
// na primjer $webi_tag_open[$webi_depth] sadrži naziv otvorene oznake čije se informacije trenutno obrađuju
// $webi_depth nivo ugniježđenja oznake
// $webi_data_temp[$webi_depth][$webi_tag_open[$webi_depth]]["attrs"] niz atributa oznake
// $webi_data_temp[$webi_depth][$webi_tag_open[$webi_depth]]["data"] podaci oznake

Štampajte "podatke". $webi_tag_open [ $webi_depth]. "--" .($webi_data_temp [ $webi_depth ][ $webi_tag_open [ $webi_depth ]][ "podaci" ]). "
" ;
print_r ($webi_data_temp [ $webi_depth ][ $webi_tag_open [ $webi_depth ]][ "attrs" ]);
print "
" ;
print_r($webi_tag_open);
print "


" ;

Unset($GLOBALS [ "webi_data_temp" ]); // nakon obrade podataka brišemo cijeli niz sa podacima, pošto je tag zatvoren
unset($GLOBALS [ "webi_tag_open" ][ $webi_depth ]); // brisanje informacija o ovoj otvorenoj oznaci... otkako je zatvorena

$webi_depth --; // smanjiti gniježđenje
}
############################################

$xml_parser = xml_parser_create();
xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, istina);

// označava koje će funkcije raditi pri otvaranju i zatvaranju oznaka
xml_set_element_handler($xml_parser, "startElement", "endElement");

// specificira funkciju za rad s podacima
xml_set_character_data_handler($xml_parser, "podaci");

// otvorite datoteku
$fp = fopen($file, "r");

$perviy_vxod = 1; // zastavica za provjeru prvog unosa u datoteku
$data = "" ; // ovdje prikupljamo podatke iz datoteke u dijelovima i šaljemo ih u xml parser

// petlja dok se ne pronađe kraj datoteke
dok (! feof ($fp ) i $fp )
{
$simvol = fgetc ($fp); // čitamo jedan znak iz datoteke
$data .= $simvol ; // dodajemo ovaj znak podacima koji se šalju

// ako znak nije završna oznaka, onda se vratimo na početak petlje i dodamo još jedan znak podacima, i tako sve dok se ne pronađe krajnja oznaka
if($simvol != ">" ) (nastavi;)
// ako je završna oznaka pronađena, sada ćemo ove prikupljene podatke poslati na obradu

// provjeravamo da li je ovo prvi unos u datoteku, onda ćemo izbrisati sve što je prije oznake// jer ponekad možete naići na smeće prije početka XML-a (nespretni uređivači ili je fajl primljen skriptom sa drugog servera)
if($perviy_vxod) ( $data = strstr ($data, "

// sada bacite podatke u xml parser
if (! xml_parse ($xml_parser, $data, feof ($fp))) (

// ovdje možete obraditi i primiti greške valjanosti...
// čim se naiđe na grešku, raščlanjivanje se zaustavlja
eho"
XML greška: " . xml_error_string(xml_get_error_code($xml_parser));
echo "na liniji" . xml_get_current_line_number ($xml_parser);
break;
}

// nakon raščlanjivanja, odbaciti prikupljene podatke za sljedeći korak ciklusa.
$data = "" ;
}
fclose($fp);
xml_parser_free($xml_parser);
// uklanjanje globalnih varijabli
unset($GLOBALS [ "webi_depth" ]);
unset($GLOBALS [ "webi_tag_open" ]);
unset($GLOBALS [ "webi_data_temp" ]);

Webi_xml("1.xml");

?>

Cijeli primjer je popraćen komentarima, sada testirajte i eksperimentirajte.
Imajte na umu da se u funkciji rada s podacima podaci ne ubacuju jednostavno u niz, već se dodaju pomoću " .=" budući da podaci možda neće stići u cijelosti, a ako samo date zadatak, onda ćete s vremena na vrijeme primati podatke u komadima.

Pa, to je sve, sada ima dovoljno memorije za obradu datoteke bilo koje veličine, ali vrijeme rada skripte može se povećati na nekoliko načina.
Umetnite funkciju na početak skripte
set_time_limit(6000);
ili
ini_set ("max_execution_time" , "6000" );

Ili dodajte tekst u .htaccess datoteku
php_value max_execution_time 6000

Ovi primjeri će povećati vrijeme izvođenja skripte na 6000 sekundi.
Na ovaj način možete povećati vrijeme samo kada je siguran način rada isključen.

Ako imate pristup uređivanju php.ini, možete povećati vrijeme korištenja
max_execution_time = 6000

Na primjer, na Masterhost hostingu, u vrijeme pisanja ovog članka, povećanje vremena skripte je zabranjeno, uprkos siguran način, ali ako ste profesionalac, možete napraviti svoj vlastiti php build na masterhost-u, ali to nije u ovom članku.

XML raščlanjivanje u suštini znači prolazak kroz XML dokument i vraćanje odgovarajućih podataka. I iako sve veći broj web servisa vraća podatke na JSON format ali većina još uvijek koristi XML, tako da je važno savladati XML raščlanjivanje ako želite koristiti cijeli raspon dostupnih interfejsa API.

Korištenje ekstenzije SimpleXML u PHP-u, koji je dodat u PHP 5.0, rad sa XML-om je veoma lak i jednostavan. U ovom članku ću vam pokazati kako to učiniti.

Osnove upotrebe

Počnimo sa sljedećim primjerom languages.xml:


>

> 1972>
> Dennis Ritchie >
>

> 1995>
> Rasmus Lerdorf >
>

> 1995>
> James Gosling >
>
>

Ovaj XML dokument sadrži listu programskih jezika sa nekim informacijama o svakom jeziku: godinu kada je uveden i ime njegovog tvorca.

Prvi korak je učitavanje XML-a pomoću funkcija simplexml_load_file(), ili simplexml_load_string(). Kao što naziv funkcija govori, prva će učitati XML iz datoteke, a druga će učitati XML iz niza.

Obje funkcije čitaju cijelo DOM stablo u memoriju i vraćaju objekt SimpleXMLElement. U gornjem primjeru, objekt je pohranjen u varijablu $languages. Možete koristiti funkcije var_dump() ili print_r() da dobijete detalje o vraćenom objektu ako želite.

SimpleXMLElement Objekat
[lang] => Niz
[ 0 ] => SimpleXMLElement objekat
[@attributes] => Niz
[ime] => C
[pojavio] => 1972
[kreator] => Dennis Ritchie
[ 1 ] => SimpleXMLElement objekat
[@attributes] => Niz
[name] => PHP
[pojavio] => 1995
[kreator] => Rasmus Lerdorf
[ 2 ] => SimpleXMLElement objekat
[@attributes] => Niz
[name] => Java
[pojavio] => 1995
[kreator] => James Gosling
)
)

Ovaj XML sadrži korijenski element jezicima, unutar koje se nalaze tri elementa lang. Svaki element niza odgovara elementu lang u XML dokumentu.

Možete pristupiti svojstvima objekta koristeći operator -> . Na primjer, $languages->lang će vam vratiti SimpleXMLElement objekat koji odgovara prvom elementu lang. Ovaj objekat sadrži dva svojstva: pojavio se i kreator.

$languages ​​-> lang [ 0 ] -> pojavio se ;
$languages ​​-> lang [ 0 ] -> creator ;

Prikazivanje liste jezika i prikazivanje njihovih svojstava može se vrlo lako uraditi pomoću standardne petlje kao što je npr za svaki.

foreach ($languages ​​-> lang kao $lang ) (
printf(
"" ,
$lang [ "name" ] ,
pojavio se $lang -> ,
$lang -> kreator
) ;
}

Obratite pažnju kako sam pristupio imenu atributa lang da bih dobio naziv jezika. Na ovaj način možete pristupiti bilo kojem atributu elementa predstavljenom kao SimpleXMLElement objekt.

Rad sa prostorima imena

Dok radite sa XML-om raznih web servisa, više puta ćete naići na prostore imena elemenata. Hajde da promenimo naše languages.xml da pokažem primjer korištenja imenskog prostora:



xmlns:dc =>

> 1972>
> Dennis Ritchie >
>

> 1995>
> Rasmus Lerdorf >
>

> 1995>
> James Gosling >
>
>

Sada element kreator uklapa se u imenski prostor dc koji upućuje na http://purl.org/dc/elements/1.1/. Ako pokušate ispisati kreatore jezika koristeći naš prethodni kod, to neće uspjeti. Da biste pročitali imenske prostore elemenata morate koristiti jedan od sljedećih pristupa.

Prvi pristup je korištenje URI imena direktno u kodu kada se pristupa imenskom prostoru elementa. Sljedeći primjer pokazuje kako se to radi:

$dc = $jezici -> lang [ 1 ] - > djeca( "http://purl.org/dc/elements/1.1/") ;
echo $dc -> kreator ;

Metoda djeca() uzima imenski prostor i vraća podređene elemente koji počinju prefiksom. Potrebna su dva argumenta, od kojih je prvi XML imenski prostor, a drugi je neobavezni argument koji je zadano false. Ako je drugi argument postavljen na TRUE, imenski prostor će se tretirati kao prefiks. Ako je FALSE, tada će se imenski prostor tretirati kao URL imenski prostor.

Drugi pristup je čitanje URI imena iz dokumenta i njihovo korištenje pri pristupu imenskom prostoru elementa. Ovo je zapravo bolji način pristupa elementima jer ne morate biti tvrdo kodirani za URI.

$namespaces = $languages ​​-> getNamespaces (true) ;
$dc = $jezici -> lang [ 1 ] -> djeca (($namespaces [ "dc" ] ) ;

echo $dc -> kreator ;

Metoda GetNamespaces() vraća niz imena prefiksa i njihovih pridruženih URI-ja. Prihvata dodatni parametar koji je zadano postavljen false. Ako postavite kao istinito, onda će ova metoda vratiti imena korištena u nadređenom i podređenom čvoru. Inače, pronalazi prostore imena koji se koriste samo u nadređenom čvoru.

Sada možete iterirati kroz listu jezika ovako:

$languages ​​= simplexml_load_file ("languages.xml") ;
$ns = $languages ​​-> getNamespaces (true);

foreach ($languages ​​-> lang kao $lang ) (
$dc = $lang -> djeca ($ns [ "dc" ] ) ;
printf(
"

%s se pojavio u %d i kreirao ga je %s.

" ,
$lang [ "name" ] ,
pojavio se $lang -> ,
$dc -> kreator
) ;
}

Praktični primjer - Parsiranje video kanala sa YouTube-a

Pogledajmo primjer koji dobija RSS feed sa YouTube kanala i prikazuje linkove na sve video zapise sa njega. Da biste to učinili, obratite se na sljedeću adresu:

http://gdata.youtube.com/feeds/api/users/xxx/uploads

URL vraća listu najnovijih video zapisa sa datog kanala u XML formatu. Analizirat ćemo XML i dobiti sljedeće informacije za svaki video:

  • Link do videa
  • Minijaturno
  • Ime

Započet ćemo pretraživanjem i učitavanjem XML-a:

$channel = "Channel_name" ;
$url = "http://gdata.youtube.com/feeds/api/users/". $channel. "/uploads" ;
$xml = file_get_contents($url);

$feed = simplexml_load_string ($xml) ;
$ns = $feed -> getNameSpaces (true) ;

Ako pogledate XML feed, možete vidjeti da tamo ima nekoliko elemenata entiteta, od kojih svaka trgovina detaljne informacije o određenom videu sa kanala. Ali koristimo samo sličice slika, URL videozapisa i naslov. Ova tri elementa su potomci elementa grupa, koji je, pak, dijete ulazak:

>

>



Naslov… >

>

>

Samo ćemo proći kroz sve elemente ulazak, a za svaki od njih ćemo izdvojiti potrebne informacije. Zapiši to igrač sličica I naslov nalaze se u imenskom prostoru medija. Dakle, moramo nastaviti kao u prethodnom primjeru. Dobijamo imena iz dokumenta i koristimo imenski prostor kada pristupamo elementima.

foreach ($feed -> unos kao $entry) (
$group = $entry -> djeca ($ns [ "mediji" ] ) ;
$grupa = $grupa -> grupa ;
$thumbnail_attrs = $grupa -> sličica [ 1 ] -> atributi () ;
$image = $thumbnail_attrs [ "url" ] ;
$player = $group -> player -> attributes () ;
$link = $player [ "url" ] ;
$title = $grupa -> naslov ;
printf( "

" ,
$player, $image, $title);
}

Zaključak

Sada kada znate kako da koristite SimpleXML Za raščlanjivanje XML podataka, možete poboljšati svoje vještine raščlanjivanjem različitih XML feedova s ​​različitim API-jima. Ali važno je uzeti u obzir da SimpleXML čita cijeli DOM u memoriju, tako da ako analizirate veliki skup podataka, možda će vam ponestati memorije. Da biste saznali više o SimpleXML-u, pročitajte dokumentaciju.


Ako imate bilo kakvih pitanja, preporučujemo da koristite našu