Osnovna upotreba SimpleXML-a. Parsing XML podataka Primjer #5 Korištenje atributa

Osnovna upotreba SimpleXML-a.  Parsing XML podataka Primjer #5 Korištenje atributa
Osnovna upotreba SimpleXML-a. Parsing XML podataka Primjer #5 Korištenje atributa

Sada ćemo učiti rad sa XML-om. XML je format za razmjenu podataka između web lokacija. Vrlo je sličan HTML-u, ali XML dozvoljava svoje vlastite oznake i atribute.

Zašto je XML potreban za raščlanjivanje? Ponekad se desi da stranica koju trebate raščlaniti ima API pomoću kojeg možete dobiti ono što želite bez mnogo truda. Stoga, samo jedan savjet – prije raščlanjivanja stranice provjerite ima li API.

Šta je API? Ovo je skup funkcija pomoću kojih možete poslati zahtjev ovoj stranici i dobiti željeni odgovor. Ovaj odgovor najčešće dolazi u XML formatu. Pa počnimo da ga proučavamo.

Rad sa XML-om u PHP-u

Recimo da imate XML. Može biti u nizu, ili pohranjen u datoteci, ili serviran na zahtjev na određeni URL.

Neka XML bude pohranjen u nizu. U ovom slučaju, trebate kreirati objekt iz ovog niza koristeći novi SimpleXMLElement:

$str = " Kolya 25 1000 "; $xml = novi SimpleXMLElement($str);

Sada imamo u varijablu $xml objekt s raščlanjenim XML-om je pohranjen. Pristupanjem svojstvima ovog objekta, možete pristupiti sadržaju XML oznaka. U nastavku ćemo pogledati kako tačno.

Ako je XML pohranjen u datoteci ili poslan pristupom URL-u (što je najčešće slučaj), tada biste trebali koristiti funkciju simplexml_load_file, što čini isti objekat $xml:

Kolya 25 1000

$xml = simplexml_load_file(putanja do datoteke ili URL);

Metode rada

U primjerima ispod, naš XML je pohranjen u datoteci ili URL-u.

Neka bude dat sljedeći XML:

Kolya 25 1000

Uzmimo ime zaposlenog, godine i platu:

$xml = simplexml_load_file(putanja do datoteke ili URL); echo $xml->name; // će prikazati "Kolya" echo $xml->age; // će ispisati 25 echo $xml->salary; // će izbaciti 1000

Kao što vidite, $xml objekat ima svojstva koja odgovaraju oznakama.

Možda ste primijetili da je oznaka ne pojavljuje se nigdje u žalbi. To je zato što je to root tag. Možete ga preimenovati, na primjer, u - i ništa se neće promijeniti:

Kolya 25 1000

$xml = simplexml_load_file(putanja do datoteke ili URL); echo $xml->name; // će prikazati "Kolya" echo $xml->age; // će ispisati 25 echo $xml->salary; // će izbaciti 1000

U XML-u može postojati samo jedna root oznaka, baš kao u običnom HTML-u.

Modificirajmo malo naš XML:

Kolya 25 1000

U ovom slučaju ćemo dobiti lanac zahtjeva:

$xml = simplexml_load_file(putanja do datoteke ili URL); echo $xml->worker->name; // će prikazati "Kolya" echo $xml->worker->age; // će izbaciti 25 echo $xml->worker->salary; // će izbaciti 1000

Rad sa atributima

Neka se neki podaci pohranjuju u atribute:

Broj 1

$xml = simplexml_load_file(putanja do datoteke ili URL); echo $xml->worker["name"]; // će prikazati "Kolya" echo $xml->worker["age"]; // će ispisati 25 echo $xml->worker["salary"]; // će izbaciti 1000 echo $xml->worker; // će prikazati "Broj 1"

Oznake sa crticama

XML dozvoljava oznake (i atribute) sa crticom. U ovom slučaju, pristup takvim oznakama se događa ovako:

Kolya Ivanov

$xml = simplexml_load_file(putanja do datoteke ili URL); echo $xml->worker->(ime); // će prikazati "Kolya" echo $xml->worker->(prezime); // će prikazati "Ivanov"

Petlja

Hajde da sada imamo ne jednog zaposlenog, već nekoliko. U ovom slučaju, možemo iterirati preko našeg objekta koristeći foreach petlju:

Kolya 25 1000 Vasya 26 2000 Peter 27 3000

$xml = simplexml_load_file(putanja do datoteke ili URL); foreach ($xml kao $worker) ( echo $worker->name; // će prikazati "Kolya", "Vasya", "Petya" )

Od objekta do normalnog niza

Ako vam nije ugodno raditi sa objektom, možete ga pretvoriti u normalan PHP niz koristeći sljedeći trik:

$xml = simplexml_load_file(putanja do datoteke ili URL); var_dump(json_decode(json_encode($xml), true));

Više informacija

Parsing baziran na sitemap.xml

Često web lokacija ima datoteku sitemap.xml. Ova datoteka pohranjuje veze do svih stranica web-mjesta radi lakšeg indeksiranja od strane pretraživača (indeksiranje je u suštini raščlanjivanje stranice od strane Yandex-a i Google-a).

Općenito, ne bismo trebali puno brinuti zašto je ova datoteka potrebna, glavna stvar je da ako postoji, ne morate puzati po stranicama web-mjesta koristeći bilo kakve lukave metode, već jednostavno koristite ovu datoteku.

Kako provjeriti prisustvo ove datoteke: raščlanimo web lokaciju site.ru, a zatim idite na site.ru/sitemap.xml u pretraživaču - ako vidite nešto, onda je tu, a ako ne vidite, onda avaj.

Ako postoji mapa sajta, onda ona sadrži veze ka svim stranicama sajta u XML formatu. Mirno uzmite ovaj XML, analizirajte ga, odvojite veze do stranica koje su vam potrebne na bilo koji način koji vam odgovara (na primjer, analizom URL-a, koji je opisan u metodi pauka).

Kao rezultat, dobijate listu veza za raščlanjivanje, sve što treba da uradite je da odete do njih i analizirate sadržaj koji vam je potreban.

Pročitajte više o uređaju sitemap.xml na Wikipediji.

Šta treba da uradite sledeće:

Započnite rješavanje zadataka koristeći sljedeći link: zadaci za lekciju.

Kada sve odlučite, pređite na proučavanje nove teme.

XML raščlanjivanje u suštini znači prolazak kroz XML dokument i vraćanje odgovarajućih podataka. Iako sve veći broj web servisa vraća podatke u JSON formatu, većina i dalje koristi XML, tako da je važno savladati XML raščlanjivanje ako želite koristiti cijeli niz dostupnih API-ja.

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 npr za svaki.

foreach ($languages ​​-> lang kao $lang ) (
printf(
"" ,
$lang [ "name" ] ,
$lang -> pojavio ,
$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" ] ,
$lang -> pojavio ,
$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 svaki pohranjuje detaljne informacije o određenom videu s kanala. Ali koristimo samo sličice slika, URL videozapisa i naslov. Ova tri elementa su potomci elementa grupa, koji je, pak, dijete ulaz:

>

>



Naslov… >

>

>

Samo ćemo proći kroz sve elemente ulaz, 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 ćete ostati bez memorije. Da biste saznali više o SimpleXML-u, pročitajte dokumentaciju.


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


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.

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 XML obrade - 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 dobivanja objekta iz XML datoteke

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 memorije i ne uzrokuje opterećenje, ali s vremenom pogoršava problem. Kako s vremenom pokušati riješiti problem, 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 pretvara sve nazive oznaka 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 otvaranje specificirane datoteke, ponavljanje kroz datoteku jedan po jedan znak i svaki znak se dodaje string varijabli dok se ne pronađe karakter > .
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 koje želite, možete poslati veliki fajl procesoru.

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 trenutno otvorenih oznaka
$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 tome što je siguran način isključen, ali ako ste profesionalac, možete napraviti svoju PHP verziju na Masterhost-u, ali to nije tema ovog članka.

Faza 1. Prolaženje testiranja (interakcija sa GIS GMP testnim krugom) #GIS GMP adresa usluge testiranja:
gisgmp.wsdlLocation=http://213.59.255.182:7777/gateway/services/SID0003663?wsdl
gisgmp.wsdlLocation.endPoint=http://213.59.255.182:7777/gateway/services/SID0003663
Ova adresa je registrovana u postavkama SP-a, potrebno je da je registrujete u datoteci sa podešavanjima evidencije, navodeći vrednost TRACE. Nakon unosa navedenih vrijednosti potrebno je pokrenuti SP i ACC klijenta (restartirati ako je već pokrenut). “Kreiraj informacije o plaćanju”, ako se prođu kontrole sistema, tada će biti kreirane informacije o plaćanju. Koje će kasnije trebati istovariti.
Nakon učitavanja, potrebno je provjeriti status koristeći akciju “Zahtjev za status obrade”. Nakon toga ED Payment Information prelazi u status “Prihvaćeno od GIS GMP” -…

Dato: MSG (poruke) tabela sa mnogo unosa.
CREATETABLEmsg(idINTEGERNOTNULLPRIMARYKEY,descriptionCHAR(50)NOTNULL, date_createDATE);
zadatak:
Potrebno je očistiti tabelu podataka/
Rješenje: Postoji nekoliko načina za rješavanje ovog problema. Ispod je opis i primjer svakog od njih.
Najlakši način ( prva opcija) - izvršavanje operatora brisanja zapisa. Kada ga izvršite, vidjet ćete rezultat (koliko zapisa je obrisano). Zgodna stvar kada morate sa sigurnošću znati i razumjeti da li su tačni podaci izbrisani. ALI ima nedostatke u odnosu na druge opcije za rješavanje problema.

DELETE FROMmsg;--Briše sve redove u tabeli --Briše sve redove sa datumom kreiranja "2019.02.01" DELETE FROMmsg WHEREdate_create="2019.02.01";

Druga opcija. Upotreba DML izraza za brisanje svih redova u tabeli.
TRUNCATETABLEmsg;
Postoji nekoliko mogućnosti korištenja ovog operatora:
Nije dostupno u Firebirdu, pa koristimo prvu i treću opciju nakon završetka…

Aktuelne adrese za zahteve prema SMEV 3.0 Podsećamo da je, u skladu sa prethodno objavljenim informacijama na Tehnološkom portalu SMEV 3.0, neophodno koristiti aktuelne adrese za Jedinstvenu elektronsku uslugu:
adresu objedinjene elektronske usluge razvojnog okruženja SMEV 3.0, koja odgovara šemi 1.1 - http://smev3-d.test.gosuslugi.ru:7500/smev/v1.1/ws?wsdl, a usluga će takođe biti dostupan na

XML Extensible Markup Language je skup pravila za kodiranje dokumenata u mašinski čitljivom obliku. XML je popularan format za razmjenu podataka na Internetu. Web lokacije koje često ažuriraju svoj sadržaj, kao što su vijesti ili blogovi, često pružaju XML feed tako da vanjski programi budu svjesni promjena sadržaja. Slanje i raščlanjivanje XML podataka je uobičajen zadatak za aplikacije povezane na mrežu. Ova lekcija objašnjava kako raščlaniti XML dokumente i koristiti njihove podatke.

Odabir parsera

Analiza kanala

Prvi korak u raščlanjivanju feeda je da odlučite koja polja podataka vas zanimaju. Parser izdvaja data polja i zanemaruje sve ostalo.

Evo isječka kanala koji će biti istražen u primjeru aplikacije. Svaki post na StackOverflow.com pojavljuje se u feedu kao ulazna oznaka, koja sadrži nekoliko podtagova:

najnovija pitanja s oznakom android - Stack Overflow ... ... http://stackoverflow.com/q/9439999 0 Gdje je moj fajl sa podacima? cliff2310 http://stackoverflow.com/users/1128925 2012-02-25T00:30:54Z 2012-02-25T00:30:54Z

Imam aplikaciju za koju je potreban fajl sa podacima...

... ...

Uzorak aplikacije dohvaća podatke iz oznake za unos i njenih podoznaka title , link , i summary .

Kreiranje instance parsera

Sljedeći korak je instanciranje parsera i pokretanje procesa raščlanjivanja. Ovaj isječak inicijalizira parser da ne rukuje prostorima imena i da koristi dostavljeni InputStream kao ulaz. Proces raščlanjivanja počinje pozivom nextTag() i poziva metodu readFeed() koja dohvaća i obrađuje podatke za koje je aplikacija zainteresirana:

Javna klasa StackOverflowXmlParser ( // Ne koristimo prostore imena privatni statički finalni String ns = null; javna lista parse(InputStream in) izbacuje XmlPullParserException, IOException ( pokušajte ( XmlPullParser parser = Xml.newPullParser(); parser.XmPullParser(); parser.XmPullParser(); parser.XmPullParser(); parser.XmPullParser(); parser.XmFACESPEll. , false parser.setInput(in, null parser.nextTag() return readFeed(parser) finally (in.close(); )

Oduzmi kanal

Metoda readFeed() obavlja stvarni posao obrade feeda. Elementi označeni oznakom "entry" su polazna tačka za rekurzivnu obradu kanala. Ako sljedeća oznaka nije oznaka za unos, ona se preskače. Nakon što je cijeli "feed" rekurzivno obrađen, readFeed() vraća Listu koja sadrži unose (uključujući ugniježđene stavke podataka) koje se preuzimaju iz feeda. Parser vraća ovu listu.

Privatna lista readFeed(XmlPullParser parser) izbacuje XmlPullParserException, IOException ( List entries = new ArrayList (); parser.require(XmlPullParser.START_TAG, ns, "feed"); while (parser.next() != XmlPull)Par (if.END_TAG)Parser (parser.getEventType() != XmlPullParser.START_TAG) (nastavi; ) String name = parser.getName(); // Počinje traženjem oznake za unos if (name.equals("entry")) (entries.add(); readEntry(parser) ) else (skip(parser); ) ) return entries;

XML raščlanjivanje

Koraci za raščlanjivanje XML feed-a su sljedeći:

Ovaj isječak pokazuje kako parser analizira unos, naslov, vezu i sažetak.

Javna statička klasa Entry (javni konačni naslov stringa; javna konačna string veza; javni konačni sažetak stringa; privatni unos (naslov stringa, sažetak stringa, veza niza) ( this.title = naslov; this.summary = sažetak; this.link = veza ; ) ) // Parsira sadržaj unosa. Ako naiđe na oznaku naslova, sažetka ili veze, predajte ih // njihovim odgovarajućim metodama "čitanja" na obradu. U suprotnom, preskočite oznaku. privatni unos readEntry(XmlPullParser parser) izbacuje XmlPullParserException, IOException ( parser.require(XmlPullParser.START_TAG, ns, "entry"); String title = null; String summary = null; String link = null; while (parser)! = XmlPullParser.END_TAG) ( if (parser.getEventType() != XmlPullParser.START_TAG) ( nastavi; ) Ime niza = parser.getName(); if (name.equals("title")) ( title = readTitle(parser) ) else if (name.equals("summary")) ( summary = readSummary(parser); ) else if (name.equals("link")) (link = readLink(parser); ) else (skip(parser) ) ) vrati novi unos (naslov, sažetak, veza) // Obrađuje oznake naslova u feedu. privatni string readTitle(XmlPullParser parser) izbacuje IOException, XmlPullParserException ( parser.require(XmlPullParser.START_TAG, ns, "title"); String title = readText(parser); parser.require(XmlPullParser,END_TAG); return title ) // Obrađuje oznake linkova u feedu. private String readLink(XmlPullParser parser) izbacuje IOException, XmlPullParserException ( String link = ""; parser.require(XmlPullParser.START_TAG, ns, "link"); String tag = parser.getName(); String relType = parserValull(nu parser.getAet) , "rel" if (tag.equals("link")) (if (relType.equals("alternate"))(link = parser.getAttributeValue(null, "href"); parser.nextTag(); ) ) parser.require(XmlPullParser.END_TAG, ns, "link" return link) // Obrađuje oznake sažetka u feedu. privatni String readSummary(XmlPullParser parser) baca IOException, XmlPullParserException ( parser.require(XmlPullParser.START_TAG, ns, "summary"); String summary = readText(parser); parser.require(XmlPullParser, "END_TAGsullParserns"); return summary ) // Za tagove title i summary, izdvaja njihove tekstualne vrijednosti. privatni String readText(XmlPullParser parser) izbacuje IOException, XmlPullParserException ( String rezultat = ""; if (parser.next() == XmlPullParser.TEXT) ( rezultat = parser.getText(); parser.nextTag(); ) vraća rezultat; ) ... )

Preskakanje stavki koje vam nisu potrebne

U jednom od gore opisanih koraka XML raščlanjivanja, parser preskače oznake koje nas ne zanimaju. Ispod je kod parsera za metodu skip():

Privatni void skip(XmlPullParser parser) izbacuje XmlPullParserException, IOException ( if (parser.getEventType() != XmlPullParser.START_TAG) ( izbaci novi IllegalStateException(); ) int dubina = 1; while (dubina 0) ( switchparser 0). next()) ( case XmlPullParser.END_TAG: dubina--; prekid; case XmlPullParser.START_TAG: dubina++; prekid; ) ) )

Evo kako to funkcionira:

  • Metoda izbacuje izuzetak ako trenutni događaj nije START_TAG.
  • Troši START_TAG, i sve događaje do END_TAG.
  • Kako bi bio siguran da se zaustavlja na ispravnoj END_TAG, a ne na prvoj oznaci nakon originalne START_TAG, prati dubinu ugniježđenja.

Dakle, ako trenutni element ima ugniježđene elemente, vrijednost dubine neće biti 0 sve dok parser ne obradi sve događaje između originalnog START_TAG i njegovog odgovarajućeg END_TAG . Na primjer, razmotrite kako analizator prolazi element koji ima 2 ugniježđena elementa, I :

  • Prilikom prvog prolaska kroz while petlju, sljedeća oznaka na koju analizator nailazi ovo je START_TAG za
  • Prilikom drugog prolaska kroz while petlju, sljedeća oznaka na koju se analizator susreće je END_TAG
  • Prilikom trećeg prolaska kroz while petlju, sljedeća oznaka na koju se analizator susreće je START_TAG . Vrijednost dubine se povećava na 2.
  • Prilikom četvrtog prolaska kroz while petlju, sljedeća oznaka na koju se analizator susreće je END_TAG. Vrijednost dubine je smanjena na 1.
  • Na petom i posljednjem prolazu kroz while petlju, sljedeća oznaka na koju se analizator susreće je END_TAG. Vrijednost dubine se smanjuje na 0, što ukazuje na to element je uspješno preskočen.

XML obrada podataka

Primjer aplikacije prima i analizira XML feed u AsyncTask. Obrada se događa izvan glavne UI niti. Kada se obrada završi, aplikacija ažurira korisnički interfejs u glavnoj aktivnosti (NetworkActivity).

U isječku ispod, metoda loadPage() radi sljedeće:

  • Inicijalizira varijablu stringa s URL-om koji upućuje na XML feed.
  • Ako korisnička podešavanja i mrežna veza dozvoljavaju, poziva novi DownloadXmlTask().execute(url) . Ovo kreira novi DownloadXmlTask ​​objekat (AsyncTask podklasu) i izvršava njegovu metodu execute(), koja preuzima i analizira cev i vraća rezultat niza koji će biti prikazan u korisničkom sučelju.
javna klasa NetworkActivity proširuje aktivnost (javni statički konačni string WIFI = "Wi-Fi"; javni statički konačni string ANY = "Bilo koji"; privatni statički konačni string URL = "http://stackoverflow.com/feeds/tag?tagnames=android&sort =newest"; // Da li postoji Wi-Fi veza. private static boolean wifiConnected = false; // Postoji li mobilna veza. private static boolean mobileConnected = false; // Da li treba osvježiti prikaz. public static boolean refreshDisplay = true public static String sPref = null ... // Koristi AsyncTask za preuzimanje XML feed-a sa stackoverflow.com public void loadPage() (if((sPref.equals(ANY)) && (wifiConnected || mobileConnected). ) ( novi DownloadXmlTask().execute(URL); ) else if ((sPref.equals(WIFI)) && (wifiConnected)) (novi DownloadXmlTask().execute(URL); ) else ( // prikaži grešku ) )
  • doInBackground() izvršava metodu loadXmlFromNetwork(). On prosljeđuje URL kanala kao parametar. Metoda loadXmlFromNetwork() prima i obrađuje kanal. Kada završi obradu, vraća rezultujući niz.
  • onPostExecute() uzima vraćeni niz i prikazuje ga u korisničkom sučelju.
// Implementacija AsyncTask-a koji se koristi za preuzimanje XML feed-a sa stackoverflow.com. privatna klasa DownloadXmlTask ​​proširuje AsyncTask ( @Override zaštićeni String doInBackground(String... urls) (pokušaj (vrati loadXmlFromNetwork(urls); ) catch (IOException e) (vrati getResources().getString(R.string.connection_error); ) catch (XmlPullParserException e) ( return getResources().getString(R.string.xml_error ) @Override protected void onPostExecute(String result) (setContentView(R.layout.main); // Prikazuje HTML string u korisničkom sučelju preko WebView WebView myWebView = (); WebView) findViewById(R.id.webview myWebView.loadData(result, "text/html", null));

Ispod je metoda loadXmlFromNetwork() koja se poziva iz DownloadXmlTask. Radi sljedeće:

  1. Kreira instancu StackOverflowXmlParser. Također kreira varijable za objekte List Entry, naslov, url i sažetak, za pohranjivanje vrijednosti ekstrahovanih iz XML feeda za ova polja.
  2. Poziva downloadUrl() koji preuzima kanal i vraća ga kao InputStream.
  3. Koristi StackOverflowXmlParser za raščlanjivanje InputStream-a. StackOverflowXmlParser popunjava unose liste podacima iz feeda.
  4. Obrađuje listu unosa i kombinuje podatke kanala sa HTML oznakama.
  5. Vraća HTML string prikazan u korisničkom sučelju glavne aktivnosti, AsyncTask, u metodi onPostExecute().
// Učitava XML sa stackoverflow.com, analizira ga i kombinuje sa // HTML oznakom. Vraća HTML string. privatni String loadXmlFromNetwork(String urlString) izbacuje XmlPullParserException, IOException ( InputStream stream = null; // Instancirajte parser StackOverflowXmlParser stackOverflowXmlParser = new StackOverflowXmlParser(); List; unosi = null; Naslov stringa = null; String url = null; Sažetak niza = null; Kalendar rightNow = Calendar.getInstance(); DateFormat formatter = new SimpleDateFormat("MMM dd h:mmaa"); // Provjerava da li je korisnik postavio postavke da uključi tekst sažetka SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); boolean pref = sharedPrefs.getBoolean("summaryPref", false); StringBuilder htmlString = new StringBuilder(); htmlString.append("

" + getResources().getString(R.string.page_title) + "

"); htmlString.append(" " + getResources().getString(R.string.updated) + " " + formatter.format(rightNow.getTime()) + ""); try ( stream = downloadUrl(urlString); entries = stackOverflowXmlParser.parse(stream); // Osigurava da je InputStream zatvoren nakon što ga aplikacija // završi s korištenjem. ) konačno ( if (stream != null) ( stream.close(); // StackOverflowXmlParser vraća Listu (nazvanu "entries") objekata Entry // Svaki Entry objekt predstavlja jednu objavu u XML feed-u // Ovaj odjeljak obrađuje listu unosa. unos sa HTML oznakom // Svaki unos se prikazuje u korisničkom sučelju kao veza koja opciono uključuje tekstualni sažetak za (Unos unosa: unosi) ( htmlString.append(").

" + entry.title + "

"); // Ako je korisnik postavio preferencije da uključi tekst sažetka, // ga dodaje na prikaz. if (pref) ( htmlString.append(entry.summary); ) ) return htmlString.toString(); ) // S obzirom na string prikaz URL-a, postavlja vezu i dobiva // ulazni tok downloadUrl(String urlString) izbacuje IOException (URL url = novi URL(urlString); HttpURLConnection conn = (HttpURLConnection) url.openConnection(). ; conn.setReadTimeout(10000 /* milisekundi */); );