XML-i sõelumine. Mittevajalike esemete vahelejätmine

XML-i sõelumine tähendab sisuliselt XML-dokumendi läbimist ja vastavate andmete tagastamist. Kuigi üha suurem hulk veebiteenuseid tagastab andmeid JSON-vormingus, kasutab enamik endiselt XML-i, seega on oluline XML-i sõelumine valdada, kui soovite kasutada kõiki saadaolevaid API-sid.

Laienduse kasutamine SimpleXML PHP 5.0-s lisatud PHP-s on XML-iga töötamine väga lihtne ja arusaadav. Selles artiklis näitan teile, kuidas seda teha.

Kasutamise põhitõed

Alustame järgmise näitega languages.xml:


>

> 1972>
> Dennis ritchie >
>

> 1995>
> Rasmus Lerdorf >
>

> 1995>
> Jamesi hanepoeg >
>
>

See XML-dokument sisaldab programmeerimiskeelte loendit koos teabega iga keele kohta: selle rakendamise aasta ja selle looja nimi.

Esimene samm on XML-i laadimine funktsioonide abil simplexml_load_file () või simplexml_load_string ()... Nagu funktsioonide nimigi viitab, laadib esimene XML-i failist ja teine ​​stringist XML-i.

Mõlemad funktsioonid loevad kogu DOM-puu mällu ja tagastavad objekti SimpleXMLElement... Ülaltoodud näites on objekt salvestatud muutujasse $ languages. Saate kasutada funktsioone var_dump () või print_r () soovi korral saada teavet tagastatava objekti kohta.

SimpleXMLElement objekt
[lang] => Massiiv
[0] => SimpleXMLElement objekt
[@ atribuudid] => Massiiv
[nimi] => C
[ilmus] => 1972
[looja] => Dennis Ritchie
[1] => SimpleXMLElement objekt
[@ atribuudid] => Massiiv
[nimi] => PHP
[ilmus] => 1995
[looja] => Rasmus Lerdorf
[2] => SimpleXMLElement objekt
[@ atribuudid] => Massiiv
[nimi] => Java
[ilmus] => 1995
[looja] => James Gosling
)
)

See XML sisaldab juurelementi keeled, mille sees on kolm elementi lang. Iga massiivi element vastab ühele elemendile lang XML-dokumendis.

Objekti omadustele pääsete juurde operaatori abil -> ... Näiteks $ languages-> lang tagastab teile SimpleXMLElement objekti, mis vastab esimesele elemendile lang... See objekt sisaldab kahte omadust: ilmunud ja looja.

$ keeled -> lang [0] -> ilmusid;
$ keeled -> keel [0] -> looja;

Keelte loendi kuvamine ja nende omaduste kuvamine on väga lihtne, kasutades standardset tsüklit, näiteks igaühele.

foreach ($ keelt -> lang kui $ lang) (
printf (
"" ,
$ lang ["nimi"],
$ lang -> ilmus,
$ lang -> looja
) ;
}

Pange tähele, kuidas pääsesin keele nime saamiseks lang-elemendi atribuudi nimele. Nii pääsete juurde SimpleXMLElement objektina esitatud elemendi mis tahes atribuudile.

Nimeruumidega töötamine

Erinevate veebiteenuste XML-iga töötades puutute elementide nimeruumidega kokku rohkem kui üks kord. Muudame oma languages.xml et näidata nimeruumi kasutamise näidet:



xmlns: dc =>

> 1972>
> Dennis ritchie >
>

> 1995>
> Rasmus Lerdorf >
>

> 1995>
> Jamesi hanepoeg >
>
>

Nüüd element looja paigutatud nimeruumi dc mis osutab aadressile http://purl.org/dc/elements/1.1/. Kui proovite keele loojaid meie eelmise koodi abil printida, siis see ei tööta. Elementide nimeruumide lugemiseks peate kasutama ühte järgmistest lähenemisviisidest.

Esimene lähenemisviis on kasutada URI-sid otse koodis, kui viidatakse elemendi nimeruumile. Järgmine näide näitab, kuidas seda tehakse:

$ dc = $ keelt -> keel [1] -> lapsed ( "http://purl.org/dc/elements/1.1/") ;
kaja $ dc -> looja;

meetod lapsed () võtab nimeruumi ja tagastab alamelemendid, mis algavad eesliitega. Selleks on vaja kahte argumenti, millest esimene on XML-nimeruum ja teine ​​valikuline argument, mis on vaikimisi vale... Kui teine ​​argument on TRUE, käsitletakse nimeruumi eesliitena. Kui VÄÄR, käsitletakse nimeruumi URL-i nimeruumina.

Teine lähenemisviis on lugeda dokumendist URI-nimed ja kasutada neid elemendi nimeruumile viitamisel. See on tegelikult parim viis elementidele juurde pääseda, sest te ei pea URI-d kõvasti kodeerima.

$ nimeruumid = $ keeled -> getNamespaces (tõene);
$ dc = $ keeled ​​-> lang [1] -> lapsed ($ nimeruumid ["dc"]);

kaja $ dc -> looja;

meetod Hangi nimeruumid () tagastab eesliidete nimede massiivi ja nendega seotud URI-d. See võtab täiendava parameetri, mis vaikimisi on vale... Kui määrate selle meeldivaks tõsi siis tagastab see meetod ema- ja alamsõlmedes kasutatud nimed. Vastasel juhul leiab see nimeruumid, mida kasutatakse ainult ülemsõlmes.

Nüüd saate keelte loendis liikuda järgmiselt.

$ keeled = simplexml_load_file ("keeled.xml");
$ ns = $ keeled -> getNamespaces (tõene);

foreach ($ keelt -> lang kui $ lang) (
$ dc = $ lang -> lapsed ($ ns ["dc"]);
printf (
"

% s ilmus % d ja selle lõi % s.

" ,
$ lang ["nimi"],
$ lang -> ilmus,
$ dc -> looja
) ;
}

Juhtumiuuring – YouTube'i videokanali sõelumine

Vaatame näidet, mis saab YouTube'i kanalilt RSS-kanali ja kuvab lingid kõigi selle videote juurde. Selleks peate võtma ühendust järgmisel aadressil:

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

URL tagastab XML-vormingus antud kanali viimaste videote loendi. Sõelume XML-i ja saame iga video kohta järgmise teabe:

  • Link videole
  • Kääbus
  • Nimi

Alustame XML-i leidmisest ja laadimisest:

$ kanal = "Kanalinimi";
$ url = "http://gdata.youtube.com/feeds/api/users/"... $ kanal. "/ üleslaadimised";
$ xml = file_get_contents ($ url);

$ feed = simplexml_load_string ($ xml);
$ ns = $ feed -> getNameSpaces (tõene);

Kui vaatate XML-voogu, näete, et seal on mitu elementi üksus, millest igaüks salvestab üksikasjalikku teavet kanali konkreetse video kohta. Kuid me kasutame ainult pisipilte, video URL-i ja pealkirja. Need kolm elementi on elemendi järeltulijad Grupp mis omakorda on laps sisenemine:

>

>



Pealkiri ... >

>

>

Me lihtsalt läbime kõik elemendid. sisenemine, ja eraldame neist igaühe kohta vajaliku teabe. pane tähele seda mängija, pisipilt ja pealkiri on meedia nimeruumis. Seetõttu peame toimima nagu eelmises näites. Nimed saame dokumendist ja elementidele viidates kasutame nimeruumi.

foreach ($ feed -> enter as $ entry) (
$ rühm = $ sisestus -> lapsed ($ ns ["meedia"]);
$ rühm = $ rühm -> rühm;
$ thumbnail_attrs = $ rühm -> pisipilt [1] -> atribuudid ();
$ pilt = $ thumbnail_attrs ["url"];
$ mängija = $ grupp -> mängija -> atribuudid ();
$ link = $ mängija ["url"];
$ pealkiri = $ grupp -> pealkiri;
printf ( "

" ,
$ mängija, $ pilt, $ pealkiri);
}

Järeldus

Nüüd, kui tead, kuidas kasutada SimpleXML XML-andmete sõelumiseks saate oma oskusi parandada, sõeludes erinevaid XML-vooge erinevate API-dega. Kuid on oluline meeles pidada, et SimpleXML loeb kogu DOM-i mällu, nii et kui sõelute suurt andmestikku, võib mälu tühjaks saada. SimpleXML-i kohta lisateabe saamiseks lugege dokumentatsiooni.


Kui teil on küsimusi, soovitame kasutada meie

Nüüd hakkame õppima XML-iga töötamist. XML on saitidevahelise andmete vahetamise vorming. See on väga sarnane HTML-iga, välja arvatud see, et XML lubab oma silte ja atribuute.

Miks vajate sõelumisel XML-i? Mõnikord juhtub nii, et saidil, mida peate sõeluma, on API, mille abil saate ilma liigse pingutuseta selle, mida soovite. Seetõttu lihtsalt nõuanne – enne saidi sõelumist kontrollige, kas sellel on API.

Mis on API? See on funktsioonide komplekt, mille abil saate sellele saidile päringu saata ja soovitud vastuse saada. See vastus tuleb enamasti XML-vormingus. Nii et asume selle uurimise juurde.

XML-iga töötamine PHP-s

Oletame, et teil on XML. See võib olla stringina või failis salvestatud või nõudmisel tagastada konkreetsele URL-ile.

Laske XML-i salvestada stringina. Sel juhul peate sellelt realt looma objekti kasutades uus SimpleXMLElement:

$ str = " Kolja 25 1000 "; $ xml = uus SimpleXMLElement ($ str);

Nüüd on meil muutuja $ xml parsitud XML-iga objekt salvestatakse. Selle objekti atribuutidele juurde pääsedes pääsete juurde XML-märgendite sisule. Kuidas täpselt - analüüsime veidi allpool.

Kui XML on salvestatud faili või tagastatakse URL-ile juurdepääsu kaudu (mis on enamasti nii), peaksite kasutama funktsiooni simplexml_load_file mis teeb sama objekti $ xml:

Kolja 25 1000

$ xml = simplexml_load_file (tee faili või URL-i);

Kuidas töötada

Allolevates näidetes on meie XML salvestatud faili või URL-i.

Olgu antud järgmine XML:

Kolja 25 1000

Võtame töötaja nime, vanuse ja palga:

$ xml = simplexml_load_file (tee faili või URL-i); echo $ xml-> nimi; // prindib "Kolya" echo $ xml-> vanus; // prindib 25 kaja $ xml-> palk; // trükib 1000

Nagu näete, on $ xml objektil siltidele vastavad omadused.

Võib-olla olete märganud, et silt ei ilmu aadressi kuhugi. Seda seetõttu, et see on juurmärgend. Saate selle näiteks ümber nimetada - ja midagi ei muutu:

Kolja 25 1000

$ xml = simplexml_load_file (tee faili või URL-i); echo $ xml-> nimi; // prindib "Kolya" echo $ xml-> vanus; // prindib 25 kaja $ xml-> palk; // trükib 1000

XML-is võib olla ainult üks juurmärgend, täpselt nagu sildis tavalises HTML-is.

Muudame veidi oma XML-i:

Kolja 25 1000

Sel juhul saame kõnede ahela:

$ xml = simplexml_load_file (tee faili või URL-i); kaja $ xml-> töötaja-> nimi; // prindib "Kolya" echo $ xml-> töötaja-> vanus; // prindib 25 kaja $ xml-> töötaja-> palk; // trükib 1000

Atribuutidega töötamine

Laske mõned andmed salvestada atribuutidesse:

Number 1

$ xml = simplexml_load_file (tee faili või URL-i); echo $ xml-> töötaja ["nimi"]; // kuvab "Kolya" echo $ xml-> töötaja ["vanus"]; // prindib 25 kaja $ xml-> töötaja ["palk"]; // prindib 1000 echo $ xml-> töötaja; // kuvab "Number 1"

Sildid sidekriipsuga

Sidekriipsuga sildid (ja atribuudid) on XML-is lubatud. Sel juhul pääseb sellistele siltidele ligi järgmiselt:

Kolja Ivanov

$ xml = simplexml_load_file (tee faili või URL-i); kaja $ xml-> töötaja -> (eesnimi); // prindib "Kolya" echo $ xml-> töötaja -> (perenimi); // kuvab "Ivanov"

Iteratsioon tsükli kaudu

Olgu meil nüüd mitte üks töötaja, vaid mitu. Sel juhul saame oma objektil itereerida, kasutades foreach-tsüklit:

Kolja 25 1000 Vasja 26 2000 Peeter 27 3000

$ xml = simplexml_load_file (tee faili või URL-i); foreach ($ xml kui $ töötaja) (kaja $ töötaja-> nimi; // prindib "Kolya", "Vasya", "Petya")

Objektist tavamassiivini

Kui teile ei meeldi mõne objektiga töötada, saate selle teisendada tavaliseks PHP massiiviks, kasutades järgmist nutikat nippi:

$ xml = simplexml_load_file (tee faili või URL-i); var_dump (json_decode (json_encode ($ xml), tõene));

Rohkem informatsiooni

Parsimine sitemap.xml põhjal

Sageli on saidil fail sitemap.xml. See fail salvestab lingid saidi kõikidele lehtedele, et hõlbustada nende indekseerimist otsingumootorite poolt (tegelikult on indekseerimine saidi sõelumine Yandexi ja Google'i poolt).

Üldiselt ei tohiks me eriti hoolida sellest, miks seda faili vaja on, peamine on see, et kui see on olemas, ei saa te saidi lehtedele ronida mis tahes kavalate meetoditega, vaid lihtsalt seda faili kasutada.

Kuidas kontrollida selle faili olemasolu: analüüsime saiti site.ru, seejärel minge brauseris saidile site.ru/sitemap.xml - kui näete midagi, siis on see seal ja kui te seda ei näe , siis paraku.

Kui saidiplaan on olemas, sisaldab see linke saidi kõikidele lehtedele XML-vormingus. Võtke see XML rahulikult, sõeluge seda, eraldage vajalike lehtede lingid teile sobival viisil (näiteks sõeludes URL-i, mida kirjeldati ämblikumeetodis).

Selle tulemusena saate parsimiseks linkide loendi, peate lihtsalt nende juurde minema ja vajaliku sisu sõeluma.

Lisateavet seadme sitemap.xml kohta leiate Vikipeediast.

Mida edasi teha?

Ülesannete lahendamist alusta järgmiselt lingilt: tunni ülesanded.

Kui olete kõik otsustanud, jätkake uue teema uurimisega.


selle artikli avaldamine on lubatud ainult koos lingiga artikli autori veebisaidile

Selles artiklis näitan teile näidet suure XML-faili sõelumise kohta. Kui teie server (hostimine) ei keela skripti tööaja pikendamist, saate sõeluda vähemalt gigabaiti kaaluvat XML-faili, ta sõelus isiklikult ainult 450 megabaiti kaaluvaid osoonifaile.

Suurte XML-failide sõelumisel on kaks probleemi:
1. Pole piisavalt mälu.
2. Skripti töötamiseks ei ole piisavalt aega eraldatud.

Teise ajaprobleemi saab lahendada, kui server seda ei keela.
Kuid mäluprobleemi on raske lahendada, isegi kui me räägime teie enda serverist, siis pole 500 megabaidiste failide teisaldamine väga lihtne ning hostimise ja VDS-i mälu suurendamine on lihtsalt võimatu.

PHP-l on mitu sisseehitatud XML-i töötlemise võimalust – SimpleXML, DOM, SAX.
Kõiki neid valikuid kirjeldatakse üksikasjalikult paljudes näidisartiklites, kuid kõik näited näitavad tööd tervikliku XML-dokumendiga.

Siin on üks näide objekti hankimisest XML-failist

Nüüd saate seda objekti töödelda, AGA ...
Nagu näete, loetakse kogu XML-fail mällu ja seejärel sõelutakse kõik objektiks.
See tähendab, et kõik andmed lähevad mällu ja kui eraldatud mälu on väike, siis skript peatub.

See valik ei sobi suurte failide töötlemiseks, peate faili rida-realt läbi lugema ja neid andmeid omakorda töötlema.
Sel juhul toimub kehtivuskontroll samamoodi nagu andmete töötlemine, mistõttu peab olema võimalik tagasi pöörata, näiteks vigase XML-faili korral kustutada kõik andmebaasi sisestatud andmed või tehke failist kaks korda läbi, esmalt lugege kehtivust, seejärel lugege andmete töötlemiseks.

Siin on teoreetiline näide suure XML-faili sõelumisest.
See skript loeb failist ühe märgi korraga, koondab need andmed plokkideks ja saadab need XML-i parserisse.
Selline lähenemine lahendab mäluprobleemi täielikult ja ei tekita stressi, vaid süvendab probleemi aja jooksul. Kuidas proovida probleemi aja jooksul lahendada, lugege allpool.

Funktsioon webi_xml ($ fail)
{

########
### funktsioon andmetega töötamiseks

{
printida $ andmed;
}
############################################



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


## lõpusildi funktsioon
funktsioon endElement ($ parser, $ nimi)
{
print $ nimi;
}
############################################

($ xml_parser, "andmed");

// avage fail
$ fp = fopen ($ fail, "r");

$ perviy_vxod = 1; $ andmed = "";



{

$ simvol = fgetc ($ fp); $ andmed = $ simvol;


if ($ simvol! = ">") (jätka;)


kaja"

murda;
}

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

Webi_xml ("1.xml");

?>

Selles näites panin kõik ühte funktsiooni webi_xml () ja kõige allosas näete selle kutset.
Skript ise koosneb kolmest põhifunktsioonist:
1. Funktsioon, mis püüab kinni märgendi startElement () avamise
2. Funktsioon, mis tabab endElement () sildi sulgemise
3. Ja andmete vastuvõtmise funktsioon ().

Oletame, et faili 1.xml sisu on mingi retsept



< title >Lihtne leib
< ingredient amount = "3" unit = "стакан" >Jahu
< ingredient amount = "0.25" unit = "грамм" >Pärm
< ingredient amount = "1.5" unit = "стакан" >Soe vesi
< ingredient amount = "1" unit = "чайная ложка" >soola
< instructions >
< step > Segage kõik koostisosad ja sõtke hoolikalt.
< step > Kata rätikuga ja jäta üheks tunniks sooja ruumi seisma..
< step > Sõtku uuesti, pane küpsetusplaadile ja pane ahju.
< step > Külastage saidi saiti


Alustuseks kutsume välja levinud funktsiooni webi_xml ("1.xml");
Lisaks sellele funktsioonile käivitub parser ja kõik siltide nimed teisendatakse suurtähtedeks, nii et kõigil siltidel on sama suurtäht.

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

Nüüd näitame, millised funktsioonid töötavad sildi avamise püüdmisel, sulgemisel ja andmete töötlemisel

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

Järgmisena avatakse määratud fail, korrates faili üks märk korraga ja iga märk lisatakse stringi muutujasse, kuni märk leitakse > .
Kui see on esimene juurdepääs failile, siis kustutatakse kõik, mis on faili alguses üleliigne, kõik, mis on enne , see on silt, millega XML peaks algama.
Esimest korda kogub stringi muutuja stringi

Ja saatke ta parserisse
xml_parse ($ xml_parser, $ andmed, feof ($ fp));
Pärast andmete töötlemist stringi muutuja visatakse ära ja andmete kogumine stringi algab uuesti ja string moodustatakse teist korda

Kolmandas
</b><br>neljandal <br><b>Lihtne leib

Pange tähele, et stringi muutuja moodustab alati valmis silt > ja ämblikule pole vaja näiteks avatud ja suletud silti koos andmetega saata
Lihtne leib
Selle töötleja jaoks on oluline saada terve mittekatkine silt, vähemalt üks avatud silt, aga järgmises etapis suletud silt või kohe 1000 rida faili, vahet pole, peaasi, et silt ei purune näiteks

le> Lihtne leib
Te ei saa sel viisil andmeid töötlejale saata, kuna silt on katki.
Saate välja mõelda oma meetodi andmete töötlejale saatmiseks, näiteks koguda 1 megabaidi andmeid ja saata need töötlejale kiiruse suurendamiseks, lihtsalt jälgige, et sildid oleksid alati täidetud ja andmed saaksid puruneda
Lihtne</b><br><b>leib

Seega saate oma soovi järgi suure faili saata töötlejale.

Nüüd vaatame, kuidas neid andmeid töödeldakse ja kuidas neid hankida.

Alustame avamissiltide funktsiooniga startElement ($ parser, $ nimi, $ attrs)
Oletame, et töötlemine on jõudnud jooneni
< ingredient amount = "3" unit = "стакан" >Jahu
Seejärel on funktsiooni sees muutuja $ nimi võrdne koostisosa ehk avatud sildi nimi (see pole veel sildi sulgemiseni jõudnud).
Samuti on sel juhul saadaval selle $ attrs sildi atribuutide massiiv, milles on andmed kogus = "3" ja ühik = "klaas".

Pärast seda funktsiooniga avatud sildi andmete töötlemine andmed ($ parser, $ andmed)
Andmemuutuja $ sisaldab kõike avamis- ja sulgemismärgendite vahel, meie puhul on selleks tekst Jahu

Ja meie stringi töötlemise lõpetab funktsioon endElement ($ parser, $ nimi)
See on suletud sildi nimi, meie puhul on $ nimi võrdne koostisosa

Ja peale seda läks kõik jälle ringi peale.

Ülaltoodud näide demonstreerib vaid XML-i töötlemise põhimõtet, kuid reaalseks kasutamiseks vajab see täiustamist.
Tavaliselt on andmete andmebaasi sisestamiseks vaja parsida suurt XML-i ning korrektseks andmetöötluseks on vaja teada, millisele avatud märgendile andmed kuuluvad, millisele sildi pesastustasemele ja millised sildid on avatud hierarhias kõrgemal. Selle teabe abil saate faili õigesti ja probleemideta töödelda.
Selleks peate sisestama mitu globaalset muutujat, mis koguvad teavet avatud siltide, pesastuste ja andmete kohta.
Siin on näide, mida saate kasutada

Funktsioon webi_xml ($ fail)
{
globaalne $ webi_depth; // loendur pesitsussügavuse jälgimiseks
$ webi_depth = 0;
globaalne $ webi_tag_open; // sisaldab praegu avatud siltide massiivi
$ webi_tag_open = massiiv ();
globaalne $ webi_data_temp; // see massiiv sisaldab ühe sildi andmeid

####################################################
### funktsioon andmetega töötamiseks
funktsiooni andmed ($ parser, $ andmed)
{
globaalne $ webi_depth;
globaalne $ webi_tag_open;
globaalne $ webi_data_temp;
// lisage massiivi andmed, mis näitavad pesastuvat ja praegu avatud silti
$ webi_data_temp [$ webi_depth] [$ webi_tag_open [$ webi_depth]] ["andmed"]. = $ andmed;
}
############################################

####################################################
### siltide avamise funktsioon
funktsioon startElement ($ parser, $ nimi, $ attrs)
{
globaalne $ webi_depth;
globaalne $ webi_tag_open;
globaalne $ webi_data_temp;

// kui pesitsustase ei ole enam null, siis on üks silt juba avatud
// ja sellelt pärinevad andmed on juba massiivis, saate neid töödelda
kui ($ webi_depth)
{




" ;

printida"
" ;
print_r ($ webi_tag_open); // avatud siltide massiiv
printida"


" ;

// pärast andmete töötlemist kustutage need mälu vabastamiseks
unset ($ GLOBALS ["webi_data_temp"] [$ webi_depth]);
}

// nüüd on alanud järgmise sildi avamine ja edasine töötlemine toimub järgmises etapis
$ webi_depth ++; // pesitsemise suurendamine

$ webi_tag_open [$ webi_depth] = $ nimi; // lisage teabemassiivi avatud silt
$ webi_data_temp [$ webi_depth] [$ nimi] ["attrs"] = $ attrs; // lisa nüüd sildi atribuudid

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

#################################################
## lõpusildi funktsioon
funktsioon endElement ($ parser, $ nimi) (
globaalne $ webi_depth;
globaalne $ webi_tag_open;
globaalne $ webi_data_temp;

// siit algab andmetöötlus, näiteks andmebaasi lisamine, faili salvestamine jne.
// $ webi_tag_open sisaldab pesastustasemete kaupa avatud siltide ahelat
// näiteks $ webi_tag_open [$ webi_depth] sisaldab avatud sildi nime, mille teavet praegu töödeldakse
// $ webi_depth sildi pesastustase
// $ webi_data_temp [$ webi_depth] [$ webi_tag_open [$ webi_depth]] ["attrs"] sildi atribuutide massiiv
// $ webi_data_temp [$ webi_depth] [$ webi_tag_open [$ webi_depth]] ["data"] märgendi andmed

Printige "andmed". $ webi_tag_open [$ webi_depth]. "-". ($ webi_data_temp [$ webi_depth] [$ webi_tag_open [$ webi_depth]] ["andmed"]). "
" ;
print_r ($ webi_data_temp [$ webi_depth] [$ webi_tag_open [$ webi_depth]] ["attrs"]);
printida"
" ;
print_r ($ webi_tag_open);
printida"


" ;

Unset ($ GLOBALS ["webi_data_temp"]); // pärast andmete töötlemist kustutage kogu massiiv koos andmetega, kuna silt suleti
unset ($ GLOBALS ["webi_tag_open"] [$ webi_depth]); // eemaldage teave selle avatud sildi kohta ... alates selle sulgemisest

$ webi_depth -; // pesitsemise vähendamine
}
############################################

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

// määrake, millised funktsioonid siltide avamisel ja sulgemisel töötavad
xml_set_element_handler ($ xml_parser, "startElement", "endElement");

// määrake funktsioon andmetega töötamiseks
xml_set_character_data_handler($ xml_parser, "andmed");

// avage fail
$ fp = fopen ($ fail, "r");

$ perviy_vxod = 1; // lipp esimese failikirje kontrollimiseks
$ andmed = ""; // siin kogume failist andmeid osade kaupa ja saadame need xml parserisse

// silmus, kuni faili lõpp leitakse
while (! feof ($ fp) ja $ fp)
{
$ simvol = fgetc ($ fp); // luges failist ühe tähemärgi
$ andmed = $ simvol; // lisage see sümbol saadetavatele andmetele

// kui märk ei ole lõpumärgend, siis läheme tagasi tsükli algusesse ja lisame andmetele veel ühe märgi ja nii edasi kuni lõpumärgend leitakse
if ($ simvol! = ">") (jätka;)
// kui leiti sulgev silt, siis nüüd saada need kogutud andmed töötlemiseks

// kontrollige, kas see on faili esimene kirje, seejärel kustutage kõik, mis on enne märgendit// kuna mõnikord võib prügi leida enne XML-i algust (kohmakad redaktorid või faili võtab skript vastu teisest serverist)
if ($ perviy_vxod) ($ data = strstr ($ andmed, "

// nüüd viskame andmed xml-parserisse
if (! xml_parse ($ xml_parser, $ andmed, feof ($ fp))) (

// siin saate töödelda ja saada kehtivuse vead ...
// niipea, kui ilmneb viga, sõelumine peatub
kaja"
XML-i viga: ". Xml_error_string (xml_get_error_code ($ xml_parser));
kaja "joonel". xml_get_current_rea_number ($ xml_parser);
murda;
}

// pärast sõelumist visake kogutud andmed tsükli järgmise etapi jaoks kõrvale.
$ andmed = "";
}
fclose ($ fp);
xml_parser_free ($ xml_parser);
// globaalsete muutujate eemaldamine
määramata ($ GLOBALS ["veebi_sügavus"]);
määramata ($ GLOBALS ["webi_tag_open"]);
määramata ($ GLOBALS ["webi_data_temp"]);

Webi_xml ("1.xml");

?>

Kogu näitega kaasnesid kommentaarid, nüüd katseta ja katseta.
Pange tähele, et andmetega töötamise funktsioonis ei sisestata andmeid lihtsalt massiivi, vaid lisatakse kasutades " .=" kuna andmed ei pruugi tulla tervikuna ja kui teed lihtsa ülesande, siis aeg-ajalt saad andmeid juppide kaupa.

Noh, see on kõik, nüüd on piisavalt mälu igas suuruses faili töötlemisel, kuid skripti tööaega saab mitmel viisil pikendada.
Sisestage funktsioon skripti algusesse
sea_time_limit (6000);
või
ini_set ("max_execution_time", "6000");

Või lisage tekst oma .htaccess-faili
php_value max_execution_time 6000

Need näited suurendavad skripti tööaega 6000 sekundini.
Sel viisil saate aega pikendada ainult keelatud režiimis.

Kui teil on juurdepääs faili php.ini redigeerimiseks, saate aega pikendada
max_täitmisaeg = 6000

Näiteks hosti põhihostis on selle kirjutamise ajal skriptiaja pikendamine keelatud, hoolimata keelatud turvarežiimist, kuid kui olete pro, saate teha masterhostis oma php-koostu, kuid see pole nii. selle kohta selles artiklis.

Mõned selle õpetuse näited sisaldavad XML-stringi. Selle asemel, et seda igas näites korrata, pange see rida faili, mille lisate igasse näitesse. See rida on näidatud järgmises näites. Lisaks saate funktsiooniga luua XML-dokumendi ja seda lugeda simplexml_load_file ().

Näide # 1 Näide.php fail XML-stringiga

$ xmlstr =<<


PHP: Parseri tutvustus


Prl. Kodeerija
Onlivia Actora


Härra. Kodeerija
El ActÓr


Nii et see on keel. See on ikkagi programmeerimiskeel. Või
kas see on skriptikeel? Kõik selgub selles dokumentaalfilmis
nagu õudusfilmis.




7
5


XML;
?>

SimpleXML-i on lihtne kasutada! Proovige saada mõni string või number aluseks olevast XML-dokumendist.

Näide # 2 Dokumendi osa toomine

sisaldama "example.php";

kaja $ filmid -> film [0] -> süžee;
?>

Nii et see on keel. See on ikkagi programmeerimiskeel. Või on see skriptikeel? Selles õudusfilmis ilmneb kõik.

PHP-s pääsete juurde XML-dokumendis olevale elemendile, mis sisaldab oma nimes kehtetuid märke (nt sidekriipsu), lisades antud elemendi nime lokkis sulgudesse ja apostroofse.

Näide # 3 Stringi otsimine

sisaldama "example.php";

kaja $ filmid -> film -> ("great-lines") -> rida;
?>

Selle näite tulemus:

PHP lahendab kõik minu veebiprobleemid

Näide # 4 Juurdepääs SimpleXML-i mitteunikaalsetele elementidele

Kui ühes vanemelemendis on mitu alamelementide eksemplari, peate kasutama standardseid iteratsioonimeetodeid.

sisaldama "example.php";

$ filmid = uus SimpleXMLElement ($ xmlstr);

/ * Iga sõlme jaoks , kuvame nime eraldi . */
foreach ($ filmid -> film -> tegelased -> tegelane $ tegelaskujuna) (
kaja $ tegelane -> nimi, "mängib", $ tegelane -> näitleja, PHP_EOL;
}

?>

Selle näite tulemus:

Prl. Kodeerijat mängib Onlivia Actora Mr. Kodeerijat mängib El ActÓr

kommenteerida:

Omadused ( $ filmid-> film eelmises näites) ei ole massiivid. See on massiivina itereeritav.

Näide # 5 Atribuutide kasutamine

Siiani saime ainult elementide nimed ja väärtused. SimpleXML pääseb juurde ka elemendi atribuutidele. Elemendi atribuudile pääseb juurde samamoodi nagu massiivi elementidele ( massiivi).

sisaldama "example.php";

$ filmid = uus SimpleXMLElement ($ xmlstr);

/ * Juurdepääs sõlmele esimene film.
* Kuvame ka hindamisskaala. * /
foreach ($ filmid -> film [0] -> hinnang $ reitinguks) (
lüliti ((string) $ reiting ["tüüp"]) ( // Hangi elemendi atribuudid indeksi järgi
juhtum "pöidlad":
kaja $ reiting, "pöial püsti";
murda;
juhtum "tähed":
kaja $ reiting, "tähed";
murda;
}
}
?>

Selle näite tulemus:

7 pöidla üles5 tärni

Näide # 6 Elementide ja atribuutide võrdlemine tekstiga

Elemendi või atribuudi võrdlemiseks stringiga või selle funktsioonile tekstina edastamiseks peate selle stringiks üle kandma, kasutades (string)... Vastasel juhul käsitleb PHP elementi objektina.

sisaldama "example.php";

$ filmid = uus SimpleXMLElement ($ xmlstr);

if ((string) $ filmid -> film -> pealkiri == "PHP: Parseri tõus") {
printida "Minu lemmikfilm.";
}

echo htmlentities ((string) $ filmid -> film -> pealkiri);
?>

Selle näite tulemus:

Minu lemmikfilm Php: Parseri esilekerkimine

Näide # 7 Kahe elemendi võrdlemine

Kahte SimpleXMLElementi peetakse erinevaks, isegi kui need osutavad samale objektile alates PHP 5.2.0-st.

sisaldama "example.php";

$ filmid1 = uus SimpleXMLElement ($ xmlstr);
$ filmid2 = uus SimpleXMLElement ($ xmlstr);
var_dump ($ filmid1 == $ filmid2); // vale alates PHP 5.2.0-st
?>

Selle näite tulemus:

Näide # 8 XPathi kasutamine

SimpleXML sisaldab sisseehitatud XPathi tuge. Leia kõik üksused :

sisaldama "example.php";

$ filmid = uus SimpleXMLElement ($ xmlstr);

foreach ($ filmid -> xpath ("// märk") $ märgina) (
kaja $ tegelane -> nimi, "mängib", $ tegelane -> näitleja, PHP_EOL;
}
?>

"// "toimib mallina. Absoluutse tee määramiseks jätke üks kaldkriips välja.

Selle näite tulemus:

Prl. Kodeerijat mängib Onlivia Actora Mr. Kodeerijat mängib El ActÓr

Näide # 9 Väärtuste seadmine

SimpleXML-i andmed ei pea olema muutumatud. Objekt võimaldab teil manipuleerida kõigi elementidega.

sisaldama "example.php";
$ filmid = uus SimpleXMLElement ($ xmlstr);

$ filmid -> film [0] -> tegelased -> tegelane [0] -> nimi = "Miss Kodeerija";

echo $ filmid -> asXML ();
?>

Selle näite tulemus:

PHP: Parseri tutvustus Preili kodeerija Onlivia Actora Härra. Kodeerija El ActÓr 7 5

Näide # 10 Elementide ja atribuutide lisamine

Alates PHP versioonist 5.1.3 on SimpleXML-il võimalus hõlpsasti lisada alamelemente ja atribuute.

sisaldama "example.php";
$ filmid = uus SimpleXMLElement ($ xmlstr);

$ karakter = $ filmid -> film [0] -> tegelased -> addChild ("tegelane");
$ märk -> addChild ("nimi", "härra Parser");
$ karakter -> addChild ("näitleja", "John Doe");

$ reiting = $ filmid -> film [0] -> addChild ("hinnang", "PG");
$ hinnang -> addAttribute ("tüüp", "mpaa");

echo $ filmid -> asXML ();
?>

Selle näite tulemus:

PHP: Parseri tutvustus Prl. Kodeerija Onlivia Actora Härra. Kodeerija El ActÓr Härra. ParserJohn teeb Nii et see on keel. See on ikkagi programmeerimiskeel. Või on see skriptikeel? Selles õudusfilmis ilmneb kõik. PHP lahendab kõik minu veebiülesanded 7 5 PG

Näide # 11 DOM-iga suhtlemine

PHP saab teisendada XML-i sõlmed SimpleXML-ist DOM-vormingusse ja vastupidi. See näide näitab, kuidas saate SimpleXML-is DOM-i elementi muuta.

$ dom = uus DOMDokument;
$ dom -> loadXML ( "jama" );
if (! $ dom) (
kaja "Dokumendi sõelumisel ilmnes viga";
väljumine;
}

$ raamatud = simplexml_import_dom ($ dom);

kaja $ raamatud -> raamat [0] -> pealkiri;
?>

Selle näite tulemus:

4 aastat tagasi

SimpleXML-objekti massiiviks teisendamiseks on sageli välja pakutud tavaline "nipp", käivitades selle läbi json_encode () ja seejärel json_decode (). Tahaksin selgitada, miks see on halb mõte.

Kõige lihtsam on see, et SimpleXML-i eesmärk on olla lihtsam kasutada ja võimsam kui tavaline massiiv. Näiteks võite kirjutadabar -> baz ["bing"]?> ja see tähendab sama, misbar [0] -> baz [0] ["bing"]?>, olenemata sellest, kui palju riba või baz elemente on XML-is; ja kui kirjutadbar [0] -> baz [0]?> saad kogu selle sõlme stringi sisu – sealhulgas CDATA sektsioonid – olenemata sellest, kas sellel on ka alamelemente või atribuute. Samuti on teil juurdepääs nimeruumi teabele, võimalus teha lihtsaid muudatusi XML-is ja isegi võimalus "importida" DOM-objekti palju võimsamaks manipuleerimiseks. Kõik see läheb kaotsi, kui muudate objekti massiiviks, mitte ei loe selle lehe näidetest aru.

Lisaks, kuna see pole selleks otstarbeks loodud, kaotab JSON-i ja tagasi teisendamine mõnes olukorras teabe. Näiteks kõik elemendid või atribuudid nimeruumis visatakse lihtsalt kõrvale ja mis tahes tekstisisu visatakse kõrvale, kui elemendil on ka alam- või atribuudid. Mõnikord pole sellel tähtsust, kuid kui teil tekib harjumus kõik massiivideks teisendada, hakkab see teid lõpuks kipitama.

Muidugi võite kirjutada nutikama teisenduse, millel neid piiranguid ei olnud, kuid sel hetkel ei saa te SimpleXML-ist üldse mingit väärtust ja peaksite lihtsalt kasutama madalama taseme XML-i parseri funktsioone või klassi XMLReader, Te ei saa ikkagi SimpleXML-i täiendavaid mugavusfunktsioone, kuid see on teie kahju.

2 aastat tagasi

Kui teie xml-string sisaldab tõeväärtusi, mis on kodeeritud numbritega "0" ja "1", tekib elemendi otse booli kandmisel probleeme:

$ xmlstr =<<

1
0

XML;
$ väärtused = uus SimpleXMLElement ($ xmlstr);
$ truevalue = (bool) $ väärtused-> truevalue; // tõsi
$ falsevalue = (bool) $ väärtused-> valeväärtus; // ka tõsi !!!

Selle asemel peate esmalt üle kandma stringi või int:

$ truevalue = (bool) (int) $ väärtused-> truevalue; // tõsi
$ falsevalue = (bool) (int) $ väärtused-> valeväärtus; // vale

9 aastat tagasi

Kui peate oma vastuses väljastama kehtiva xml-i, ärge unustage lisaks asXML-i tulemuse kajamisele oma päise sisutüübiks seada xml ():

$ xml = simplexml_load_file ("...");
...
... xml värk
...

// väljasta oma vastuses xml:
päis ("Sisutüüp: tekst / xml");
echo $ xml -> asXML ();
?>

9 aastat tagasi

README failist:

SimpleXML on mõeldud lihtsaks viisiks XML-andmetele juurde pääseda.

SimpleXML-i objektid järgivad nelja põhireeglit:

1) omadused tähistavad elemendi iteraatoreid
2) arvindeksid tähistavad elemente
3) mittenumbrilised indeksid tähistavad atribuute
4) stringi teisendamine võimaldab juurdepääsu TEKSTI andmetele

Atribuutide itereerimisel itereerub laiend alati üle
kõik selle elemendi nimega sõlmed. Seega meetodilapsed () peavad olema
kutsutakse itereerima üle alamsõlmede. Kuid tehes ka järgmist:
foreach ($ obj-> sõlme_nimi kui $ elem) (
// tee midagi rakendusega $ elem
}
tulemuseks on alati "node_name" elementide iteratsioon. Nii et mitte edasi
seda tüüpi sõlmede arvu eristamiseks on vaja kontrollida.

Kui elemendile TEXT andmetele juurde pääsetakse atribuudi kaudu
siis ei sisalda tulemus alamelementide TEKSTI andmeid.

Teadaolevad probleemid
============

Mootoriprobleemide tõttu pole hetkel võimalik ligi pääseda
alamelement indeksi 0 järgi: $ objekt-> omadus.

8 aastat tagasi

Kui kasutate selliseid asju nagu: is_object ($ xml-> module-> admin), et kontrollida, kas seal on tõesti sõlm nimega "admin", ei paista see töötavat ootuspäraselt, kuna simplexml tagastab alati objekti - sel juhul tühja objekti - isegi kui konkreetset sõlme pole olemas.
Minu jaoks tundub, et vana hea tühi () funktsioon töötab sellistel juhtudel hästi.

8 aastat tagasi

Kiire näpunäide xpath päringute ja vaikenimeruumide kohta. Näib, et SimpleXML-i taga oleval XML-süsteemil on sama töö, mida minu arvates kasutab XML-süsteem .NET: kui on vaja midagi vaikimisi nimeruumis käsitleda, tuleb nimeruum deklareerida, kasutades registerXPathNamespace ja seejärel kasutada selle eesliidet aadress muidu vaikimisi nimeruumi elav element.

$ string =<<

Nelikümmend Mida?
Joe
Jane

Ma tean, et see on vastus – aga mis on küsimus?




XML;

$ xml = simplexml_load_string ($ string);
$ xml -> registerXPathNamespace ("def", "http://www.w3.org/2005/Atom");

$ sõlmed = $ xml -> xpath ("// def: dokument / def: pealkiri");

?>

9 aastat tagasi

Kuigi SimpleXMLElement väidab end olevat itereeritav, ei paista see rakendavat standardseid Iteraatori liidese funktsioone, nagu :: next ja :: lähtestage korralikult. Seega, kuigi foreach () töötab, ei tundu sellised funktsioonid nagu järgmine (), praegune () või kumbki () töötavat ootuspäraselt – kursor ei paista kunagi liikuvat või lähtestatakse pidevalt.

6 aastat tagasi

Kui XML-dokumendi kodeering erineb UTF-8-st, peab kodeeringu deklaratsioon järgnema kohe pärast versiooni = "..." ja enne standalone = "...". See on XML-standardi nõue.

Kui XML-dokumendi kodeering erineb UTF-8-st. Kodeeringu deklaratsioon peaks järgnema kohe pärast versiooni = "..." ja enne standalone = "...". See nõue on standardne XML.


Okei

vene keel. vene keel


Saatuslik viga: tabamata erand "Erand" sõnumiga "Stringi ei saanud XML-ina sõeluda" asukohas ...

Laiendatav märgistuskeel XML on reeglite kogum dokumentide masinloetaval kujul kodeerimiseks. XML on populaarne vorming andmete vahetamiseks Internetis. Saidid, mis värskendavad sageli oma sisu, nagu uudistesaidid või ajaveebid, pakuvad sageli XML-i voogu, et hoida välised programmid sisumuutustega kursis. XML-andmete saatmine ja sõelumine on võrgurakenduste jaoks tavaline ülesanne. Selles õppetükis selgitatakse, kuidas sõeluda XML-dokumente ja kasutada nende andmeid.

Parseri valimine

Kanali analüüs

Voo sõelumise esimene samm on otsustada, millised andmeväljad teid huvitavad. Parser ekstraheerib määratud väljad ja ignoreerib kõike muud.

Siin on voo katkend, mida uuritakse näidisrakenduses. Iga postitus saidil StackOverflow.com kuvatakse voos sisestusmärgendina, mis sisaldab mitut pesastatud silti:

uusimad küsimused sildistatud android – Stack Overflow ... ... http://stackoverflow.com/q/9439999 0 Kus on minu andmefail? kalju2310 http://stackoverflow.com/users/1128925 2012-02-25T00: 30: 54Z 2012-02-25T00: 30: 54Z

Mul on rakendus, mis nõuab andmefaili ...

... ...

Näidisrakendus eraldab andmed sisestusmärgendist ja selle alammärgenditest, pealkirjast, lingist ja kokkuvõttest.

Parseri instantseerimine

Järgmine samm on parseri käivitamine ja sõelumisprotsessi käivitamine. See koodilõik initsialiseerib parseri nii, et see ei käsitleks nimeruume, ja kasutab sisendina kaasasolevat InputStreami. Sõelumisprotsess käivitatakse kutsudes nextTag () ja kutsutakse välja readFeed () meetod, mis hangib ja töötleb rakendust huvitavad andmed:

Avalik klass StackOverflowXmlParser (// Me ei kasuta nimeruume privaatne staatiline lõplik String ns = null; avalik loendi sõelumine (InputStream in) viskab XmlPullParserExceptioni, IOExceptioni (proovige (XmlPullParser parser = Xml.newPullParser ();); parser.set.Feature, fallueParser ); parser.setInput (in, null); parser.nextTag (); tagasta readFeed (parser);) lõpuks (in.close ();)) ...)

Lahutage kanal

Meetod readFeed () teeb voo käsitlemise tegeliku töö ära. "Entry" sildiga märgitud üksused on rekursiivse kanalitöötluse lähtepunktiks. Kui järgmine silt ei ole sisestussilt, jäetakse see vahele. Pärast kogu voo rekursiivset töötlemist tagastab readFeed () loendi, mis sisaldab voost toodud kirjeid (sh pesastatud andmeüksusi). Seejärel tagastab parser selle loendi.

Private List readFeed (XmlPullParser parser) viskab XmlPullParserException, IOException (loendi kirjed = uus ArrayList (); parser.require (XmlPullParser.START_TAG, ns, "feed"); while (parser.next ()! = XmlPullParser.END_TAG getEventType ()! = XmlPullParser.START_TAG) (jätka;) Stringi nimi = parser.getName (); // Alustuseks otsitakse kirjemärgendit if (name.equals ("entry")) (entries.add ( readEntry (parser) ));) else (jäta vahele (parser);)) tagasta kirjed;)

XML-i sõelumine

XML-voo sõelumise sammud on järgmised.

See väljavõte näitab, kuidas parser sõelub kirjet, pealkirja, linki ja kokkuvõtet.

Avalik staatiline klassi kirje (avalik lõplik stringi pealkiri; avalik lõplik stringi link; avalik lõplik stringi kokkuvõte; privaatne kirje (stringi pealkiri, stringi kokkuvõte, stringi link) (this.title = pealkiri; this.summary = kokkuvõte; this.link = link ;)) // Parsib kirje sisu. Kui see kohtab pealkirja, kokkuvõtte või lingi märgendit, suunake need töötlemiseks // nende vastavatele lugemismeetoditele. Vastasel juhul jätab sildi vahele. private Entry readEntry (XmlPullParser parser) viskab XmlPullParserException, IOException (parser.require (XmlPullParser.START_TAG, ns, "entry"); stringi pealkiri = null; Stringi kokkuvõte = null; String link = null; while (parser.next ()! = XmlPullParser.END_TAG) (if (parser.getEventType ()! = XmlPullParser.START_TAG) (jätka;) Stringi nimi = parser.getName (); if (name.equals ("pealkiri")) (pealkiri = readTitle (parser) ;) else if (nimi.võrdub ("kokkuvõte")) (kokkuvõte = readSummary (parser);) else if (name.equals ("link")) (link = readLink (parser);) else (skip (parser)) ;)) return new Entry (pealkiri, kokkuvõte, link);) // Töötleb voo pealkirjamärgendeid. privaatne string readTitle (XmlPullParser parser) viskab IOException, XmlPullParserException (parser.require (XmlPullParser.START_TAG, ns, "title"); String title = readText (parser); parser.require (XmlPullParser.END); tagastab "title"; ) // Töötleb voos olevaid lingimärgendeid. privaatne stringi readLink (XmlPullParser parser) viskab IOExceptioni, XmlPullParserExceptioni (String link = ""; parser.require (XmlPullParser.START_TAG, ns, "link"); Stringi silt = parser.getName (); String relType = parser.getAttributeValue , "rel"); if (tag.equals ("link")) (if (relType.equals ("alternate")) (link = parser.getAttributeValue (null, "href"); parser.nextTag ();) ) parser.require (XmlPullParser.END_TAG, ns, "link"); tagasta link;) // Töötleb voo kokkuvõtlikke silte. private String readSummary (XmlPullParser parser) viskab IOException, XmlPullParserException (parser.require (XmlPullParser.START_TAG, ns, "summary"); String summary = readText (parser); parser.require (XmlPullParser, "END_TAG summary return summary";); ) // Siltide pealkirja ja kokkuvõtte jaoks eraldab nende tekstiväärtused. private String readText (XmlPullParser parser) viskab IOExceptioni, XmlPullParserExceptioni (Stringi tulemus = ""; if (parser.next () == XmlPullParser.TEXT) (result = parser.getText (); parser.nextTag ();) tagastab tulemuse; ) ...)

Mittevajalike esemete vahelejätmine

Ühes ülalkirjeldatud XML-i sõelumise etapis jätab parser vahele sildid, mis meid ei huvita. Allpool on vahelejätmise () meetodi parseri kood:

Privaatne tühiku vahelejätmine (XmlPullParser parser) viskab XmlPullParserException, IOException (if (parser.getEventType ()! = XmlPullParser.START_TAG) (viska uus IllegalStateException ();) int sügavus = 1; while (depth! = 0) (lüliti järgmine ()) (tähe XmlPullParser.END_TAG: sügavus--; katkestus; suurtäht XmlPullParser.START_TAG: sügavus ++; murda;)))

See toimib järgmiselt.

  • Meetod loob erandi, kui praegune sündmus ei ole START_TAG.
  • See kulutab START_TAG ja kõik sündmused kuni END_TAG.
  • Veendumaks, et see peatub õigel END_TAG, mitte esimese kokkupuute märgendil pärast algset START_TAG, jälgib see pesastussügavust.

Seega, kui praegusel elemendil on pesastatud elemente, ei ole sügavuse väärtus 0 enne, kui parser on töötlenud kõiki sündmusi algse START_TAG ja sellele vastava END_TAG vahel. Mõelge näiteks sellele, kuidas analüsaator eksib element, millel on 2 pesastatud elementi, ja :

  • Esimesel while-tsükli läbimisel järgmine silt, mida analüsaator pärast seda kohtab see on START_TAG jaoks
  • Teises while-tsükli läbimises on järgmine silt, mille analüsaator kohtab, END_TAG
  • Kolmandas while-tsükli läbimises on järgmine silt, mille analüsaator kohtab, START_TAG ... Sügavuse väärtust suurendatakse 2-ni.
  • Neljandas while-tsükli läbimises on järgmine silt, mida analüsaator kohtab, END_TAG... Sügavuse väärtus väheneb 1-ni.
  • Viiendal ja viimasel while-tsükli läbimisel on järgmine silt, mida analüsaator kohtab, END_TAG... Sügavus väheneb 0-ni, mis näitab, et üksus jäeti edukalt vahele.

XML-andmete töötlemine

Näidisrakendus võtab vastu ja analüüsib XML-voo AsyncTaski. Töötlemine toimub väljaspool kasutajaliidese peamist lõime. Kui töötlemine on lõppenud, värskendab rakendus kasutajaliidest põhitegevuses (NetworkActivity).

Alloleval lõigul teeb loadPage () meetod järgmist.

  • Initsialiseerib stringi muutuja URL-i väärtusega, mis osutab XML-kanalile.
  • Kui kasutaja seaded ja võrguühendus lubavad, kutsub välja uue DownloadXmlTask ​​​​(). Käivita (url). See loob uue DownloadXmlTask ​​​​objekti (AsyncTask alamklass) ja käivitab selle execute () meetodi, mis laadib alla ja sõelub kanali ning tagastab stringi tulemuse, mis kuvatakse kasutajaliideses.
avalik klass NetworkActivity laiendab tegevust (avalik staatiline lõplik string WIFI = "Wi-Fi"; avalik staatiline lõplik string ANY = "kõik"; privaatne staatiline lõplik stringi URL = "http://stackoverflow.com/feeds/tag?tagnames=android&sort = uusim "; // Kas WiFi-ühendus on olemas. privaatne staatiline tõeväärtus wifiConnected = false; // kas mobiilne ühendus on olemas. privaatne staatiline tõeväärtus mobileConnected = false; // Kas kuva tuleks värskendada. public staatiline tõeväärtus refreshDisplay = true; avalik staatiline string sPref = null; ... // Kasutab AsyncTaski XML-kanali allalaadimiseks saidilt stackoverflow.com. public void loadPage () (if ((sPref.equals (ANY)) && (wifiConnected || mobileConnected )) (uus DownloadXmlTask ​​​​(). käivita (URL);) else if ((sPref.equals (WIFI)) && (wifiConnected)) (uus DownloadXmlTask ​​​​(). käivita (URL);) else (// näita viga))
  • doInBackground () käivitab loadXmlFromNetwork () meetodi. See edastab parameetrina kanali URL-i. Meetod loadXmlFromNetwork () võtab kanali vastu ja töötleb seda. Kui see on töötlemise lõpetanud, edastab see saadud stringi tagasi.
  • onPostExecute () võtab tagastatud stringi ja kuvab selle kasutajaliideses.
// AsyncTaski juurutamine, mida kasutatakse XML-voo allalaadimiseks saidilt stackoverflow.com. eraklass DownloadXmlTask ​​​​laiendab AsyncTaski (@Alista kaitstud string doInBackground (String ... URL-id) (proovige (tagasta loadXmlFromNetwork (urls);) püüdmine (IOException e) (tagasi getResources (). GetString (R.string.connection_error);) püüdmine (XmlPullParserException e) ( tagasta getResources (). getString (R.string.xml_error);)) @Override protected void onPostExecute (Stringi tulemus) (setContentView (R.layout.main); // Kuvab kasutajaliideses HTML-stringi WebView WebView kaudu myWebView = (WebView) findViewById (R.id.webview); myWebView.loadData (tulemus, "text / html", null);))

Allpool on meetod loadXmlFromNetwork (), mis kutsutakse välja rakendusest DownloadXmlTask. See teeb järgmist:

  1. Loob StackOverflowXmlParseri eksemplari. Samuti loob see muutujad loendikirje objektide (kirjete) ning pealkirja, URL-i ja kokkuvõtte jaoks, et salvestada nende väljade jaoks XML-voost hangitud väärtused.
  2. Kutsub välja downloadUrl (), mis laadib kanali alla ja tagastab selle sisendvoona.
  3. Kasutab InputStreami sõelumiseks StackOverflowXmlParserit. StackOverflowXmlParser täidab loendi kirjed voo andmetega.
  4. Töötleb kirjete loendit ja ühendab vooandmed HTML-märgistusega.
  5. Tagastab HTML-stringi, mis kuvatakse põhitegevuse kasutajaliideses, AsyncTask meetodis onPostExecute ().
// Laadib saidilt stackoverflow.com üles XML-i, analüüsib seda ja ühendab selle // HTML-märgistusega. Tagastab HTML-stringi. privaatne string loadXmlFromNetwork (String urlString) viskab XmlPullParserException, IOException (InputStream voog = null; // Parseri esinemine StackOverflowXmlParser stackOverflowXmlParser = uus StackOverflowXmlParser (); loend kirjed = null; Stringi pealkiri = null; Stringi url = null; Stringi kokkuvõte = null; Calendar rightNow = Calendar.getInstance (); DateFormat vormindaja = uus SimpleDateFormat ("MMM dd h: mma"); // Kontrollib, kas kasutaja seadis eelistuse kokkuvõtliku teksti lisamiseks SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences (see); boolean pref = jagatudPrefs.getBoolean ("summaryPref", vale); StringBuilder htmlString = uus StringBuilder (); htmlString.append ("

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

"); htmlString.append (" "+ getResources (). getString (R.string.updated) +" "+ formatter.format (rightNow.getTime ()) +""); proovige (stream = downloadUrl (urlString); kirjed = stackOverflowXmlParser.parse (voog); // Veenduge, et InputStream suletakse pärast seda, kui rakendus on // selle kasutamise lõpetanud.) lõpuks (if (voog! = null) (stream.close ();)) // StackOverflowXmlParser tagastab sisestusobjektide loendi (nimetatakse "kirjeteks"). // Iga kirje objekt esindab ühte postitust XML-voos. // See jaotis töötleb kirjete loendit, et ühendada kõik kirjed. kirje HTML-märgistusega. // Iga kirje kuvatakse kasutajaliideses lingina, mis sisaldab valikuliselt // tekstikokkuvõtet. jaoks (Kirje sisestus: kirjed) (htmlString.append ("

"+ entry.title +"

"); // Kui kasutaja seadis eelistuse kokkuvõtliku teksti lisamiseks, // lisab selle kuvale. If (pref) (htmlString.append (entry.summary);)) tagastab htmlString.toString ();) // URL-i stringi esituse korral loob ühenduse ja saab // sisendi stream.private InputStream downloadUrl (String urlString) viskab IOExceptioni (URL url = uus URL (urlString); HttpURLConnection conn = (HttpURLConnection) url.openConnection () ; conn.setReadTimeout (10000 / * millisekundit * /); conn.setConnectTimeout (15000 / * millisekundit * /); conn.setRequestMethod ("GET"); conn.setDoInput (true); // Käivitab päringu conn.connect ( ); tagasta conn.getInputStream ();)