XML datu parsēšana. XML datu parsēšana, parsētāja ģenerēšana


Autors: Arsenijs Kapoulkins
Publicēšanas datums: 2012. gada 21. septembris
Tulkojums: A. Panin
Tulkošanas datums: 2013. gada 10. novembris

Ievads

XML ir standartizēta iezīmēšanas valoda, kurai ir noteikumu kopums hierarhiski strukturētu dokumentu kodēšanai cilvēkiem lasāmā veidā. teksta formātā. XML standarts ir kļuvis plaši izplatīts un tiek izmantots, lai izveidotu ļoti kompaktu vienkārši dokumenti(piemēram, SOAP pieprasījumi) un vairāku gigabaitu dokumenti (ko izmanto OpenStreetMap projekts) ar sarežģītām datu atkarībām (COLLADA). Lai apstrādātu XML dokumentus, lietotājiem parasti ir nepieciešama īpaša bibliotēka: tai ir jāievieš XML dokumentu parsētājs, kas pārvērš dokumentu no teksta dokumenta par iekšējo attēlojumu. XML standarts ir kompromiss attiecībā uz parsēšanas ātrumu, lietotāja lasāmību un parsējamā koda sarežģītību, tāpēc ātra XML dokumentu parsēšanas sistēma var ietekmēt vēlamo XML kā lietojumprogrammas datu glabāšanas formāta izvēli.

Šajā nodaļā ir aprakstīti dažādi paņēmieni, kuru mērķis ir uzlabot aprakstītās parsēšanas sistēmas veiktspēju un ļaut autoram izstrādāt ārkārtīgi produktīvu parsēšanas sistēmu, izmantojot C++ programmēšanas valodu: pugixml. Lai gan šīs metodes tika izmantotas XML dokumentu parsēšanas sistēmā, lielāko daļu no tām var izmantot citu formātu dokumentu parsēšanas sistēmās vai pat pilnīgi nesaistītos programmatūras komponentos (piemēram, atmiņas pārvaldības algoritmi tiek plaši izmantoti nesaistītās parsēšanas sistēmās teksta dokumenti apgabali).

Tā kā XML dokumentu parsēšanai ir vairākas ļoti atšķirīgas pieejas, parsēšanas sistēmai ir jādarbojas papildu darbības, ko nezina pat tie, kuriem ir pieredze darbā ar XML dokumentiem, ir svarīgi vispirms aprakstīt veicamo uzdevumu, pirms iedziļināties sīkāk par ieviešanas detaļām.

XML parsēšanas sistēmu modeļi

Katrs no dažādi modeļi XML dokumentu parsēšanas sistēmas ir optimālas noteiktās situācijās, un katram no šiem modeļiem ir savi veiktspējas un atmiņas patēriņa parametri. Visplašāk tiek izmantoti šādi modeļi:

  • Izmantojot uz SAX balstītas parsēšanas sistēmas (Simple API for XML), lietotājs saņem savā atrašanās vietā programmatūras komponents, kas sagaida dokumenta datu straumi kā ievadi un nodrošina vairākas atzvanīšanas funkcijas, piemēram, "atvērt tagu", "aizvērt tagu", "rakstzīme tagā". Dokumenta datu apstrādes laikā parsēšanas sistēma izmanto atzvanīšanas funkcijas. Parsēšanai nepieciešamo kontekstu ierobežo pašreizējā elementa koka dziļums, kas nozīmē ievērojamu atmiņas prasību samazināšanos. Šāda veida parsēšanas sistēmu var izmantot, lai apstrādātu straumētus dokumentus, ja vienlaikus ir pieejama tikai daļa no dokumenta.
  • Izvilkšanas parsēšana pēc paša procesa ir līdzīga uz SAX balstītai parsēšanai - vienlaikus tiek apstrādāts viens dokumenta elements, taču tiek mainīta parsēšanas procesa pārvaldības metode: uz SAX balstītā parsēšanas sistēmā parsēšanas procesu kontrolē pati sistēma, izmantojot atzvanīšanas funkcijas, savukārt vilkšanas parsēšanas laikā lietotājs kontrolē parsēšanas procesu, izmantojot iteratoram līdzīgu objektu.
  • Izmantojot uz DOM balstītas parsēšanas sistēmas (Document Object Model), lietotājs nodod parsēšanas sistēmai pilnīgu dokumentu bufera vai teksta datu straumes veidā, uz kura pamata parsēšanas sistēma ģenerē visa objekta atmiņu. dokumenta elementu koks, katram izmantojot atsevišķus objektus konkrētu elementu vai XML atribūts, kā arī derīgu darbību kopa (piemēram, "get all bērnu elementišis mezgls"). Pugxml bibliotēka izmanto šo modeli.

Parsēšanas sistēmas modeļa izvēle parasti ir atkarīga no dokumenta lieluma un tā struktūras. Tā kā pugixml parsē, pamatojoties uz DOM, tas ir efektīvs dokumentiem, kas:

  • ir tik maza izmēra, ka var pilnībā ietilpt atmiņā,
  • ir sarežģīta struktūra ar saitēm starp mezgliem, kas jāšķērso, vai
  • nepieciešamas sarežģītas dokumentu transformācijas.

Arhitektūras risinājumi pugixml

Pugixml bibliotēkas izstrādes laikā liela uzmanība tika pievērsta DOM attēlojuma izveides problēmai, jo, lai gan bija pieejamas ātras un vieglas uz SAX balstītas parsēšanas sistēmas (piemēram, Expat), visas DOM balstītas XML parsēšanas sistēmas bija pieejamas ražošanai. izmantošanas laikā pugixml izveides laikā (2006) nebija pārāk vieglas vai ne pārāk ātras. Pamatojoties uz to, puixml izstrādes procesa galvenais mērķis ir izveidot ļoti ātru, vieglu bibliotēku, lai veiktu uz DOM balstītas manipulācijas ar XML dokumentiem.


šī raksta publicēšana ir atļauta tikai ar saiti uz raksta autora vietni

Šajā rakstā es parādīšu piemēru, kā parsēt lielu XML failu. Ja jūsu serveris (hostings) neaizliedz palielināt skripta darbības laiku, varat parsēt XML failu, kas sver vismaz gigabaitus. Es personīgi parsēju tikai failus no ozona, kas sver 450 megabaitus.

Parsējot lielus XML failus, rodas divas problēmas:
1. Nepietiek atmiņas.
2. Nav pietiekami daudz laika, lai skripts varētu palaist.

Otro problēmu ar laiku var atrisināt, ja serveris to neaizliedz.
Bet problēmu ar atmiņu ir grūti atrisināt, pat ja mēs runājam par jūsu pašu serveri, 500 megabaitu failu pārvietošana nav ļoti vienkārša, un vienkārši nav iespējams palielināt mitināšanas un VDS atmiņu.

PHP ir iebūvētas vairākas XML apstrādes iespējas – SimpleXML, DOM, SAX.
Visas šīs opcijas ir detalizēti aprakstītas daudzos rakstos ar piemēriem, taču visi piemēri parāda darbu ar pilnu XML dokumentu.

Šeit ir viens piemērs, no kura mēs iegūstam objektu XML fails

Tagad jūs varat apstrādāt šo objektu, BET...
Kā redzat, viss XML fails tiek nolasīts atmiņā, pēc tam viss tiek parsēts objektā.
Tas ir, visi dati nonāk atmiņā un, ja nav pietiekami daudz atvēlētās atmiņas, skripts apstājas.

Šī opcija nav piemērota lielu failu apstrādei, jums ir jālasa fails pēc rindas un jāapstrādā šie dati pa vienam.
Šajā gadījumā derīguma pārbaude tiek veikta arī datu apstrādes laikā, tāpēc jums ir jābūt iespējai atsaukt, piemēram, dzēst visus datubāzē ievadītos datus nederīga XML faila gadījumā vai veikt divas piespēles. caur failu, vispirms izlasiet derīgumu, pēc tam lasiet, lai apstrādātu datus.

Šeit ir teorētisks piemērs liela XML faila parsēšanai.
Šis skripts no faila nolasa vienu rakstzīmi, apkopo šos datus blokos un nosūta tos XML parsētājam.
Šī pieeja pilnībā atrisina atmiņas problēmu un nerada slodzi, bet laika gaitā pasliktina problēmu. Kā mēģināt atrisināt problēmu laika gaitā, lasiet tālāk.

Funkcija webi_xml ($file)
{

########
### datu funkcija

{
drukāt $data ;
}
############################################



{
drukāt $name ;
print_r($attrs);
}


## aizverošā taga funkcija
funkcija endElement ($parser, $name)
{
drukāt $name ;
}
############################################

($xml_parser, "dati");

// atveriet failu
$fp = fopen($fails, "r");

$perviy_vxod = 1 ; $dati = "" ;



{

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


if($simvol != ">" ) (turpināt;)


atbalss"

pārtraukums;
}

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

Webi_xml("1.xml");

?>

Šajā piemērā es visu ievietoju vienā funkcijā webi_xml() un pašā apakšā var redzēt tās izsaukumu.
Pats skripts sastāv no trim galvenajām funkcijām:
1. Funkcija, kas uztver startElement() taga atvēršanu
2. Funkcija, kas uztver beigu endElement() tagu
3. Un datu saņemšanas funkcija data() .

Pieņemsim, ka faila 1.xml saturs ir recepte



< title >Vienkārša maize
< ingredient amount = "3" unit = "стакан" >Milti
< ingredient amount = "0.25" unit = "грамм" >Raugs
< ingredient amount = "1.5" unit = "стакан" >Silts ūdens
< ingredient amount = "1" unit = "чайная ложка" >Sāls
< instructions >
< step > Visas sastāvdaļas sajauc un kārtīgi mīca.
< step > Pārklāj ar drānu un atstāj uz stundu siltā telpā..
< step > Vēlreiz mīcīt, liek uz cepešpannas un liek cepeškrāsnī.
< step > Apmeklējiet vietnes vietni


Visu sākam, izsaucot vispārīgo funkciju webi_xml ("1.xml" );
Pēc tam šajā funkcijā sākas parsētājs, un visi tagu nosaukumi tiek pārveidoti par lielajiem burtiem, lai visiem tagiem būtu vienāds reģistrs.

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

Tagad mēs norādām, kuras funkcijas darbosies, lai uztvertu taga atvēršanu, aizvēršanu un datu apstrādi

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

Tālāk seko atklājums norādītais fails, atkārto failu pa vienai rakstzīmei un katra rakstzīme tiek pievienota virknes mainīgajam, līdz tiek atrasta rakstzīme > .
Ja šī ir pati pirmā piekļuve failam, tad pa ceļam tiks dzēsts viss, kas faila sākumā ir nevajadzīgs, viss, kas nāk pirms , ar šo tagu XML jāsākas.
Pirmo reizi virknes mainīgajā būs virkne

Un nosūtiet to demontētājam
xml_parse ($xml_parser, $data, feof ($fp));
Pēc datu apstrādes virknes mainīgais tiek atiestatīts un datu apkopošana virknē sākas no jauna un virkne tiek veidota otro reizi

Trešajā
</b><br>ceturtajā <br><b>Vienkārša maize

Lūdzu, ņemiet vērā, ka virknes mainīgais vienmēr tiek veidots no pabeigta taga > un nav nepieciešams zaglim nosūtīt atvērtu un aizvērtu tagu ar datiem, piemēram
Vienkārša maize
Šim apdarinātājam ir svarīgi saņemt veselu nelauztu tagu, vismaz vienu atvērtu tagu un nākamajā solī aizvērtu tagu vai uzreiz saņemt 1000 faila rindiņas, tas nav svarīgi, galvenais, lai tags neplīst, piemēram

le>Vienkārša maize
Tādā veidā nav iespējams nosūtīt datus apstrādātājam, jo ​​tags ir saplēsts.
Varat izdomāt savu metodi datu nosūtīšanai apstrādātājam, piemēram, savākt 1 megabaitu datu un nosūtīt to apstrādātājam, lai palielinātu ātrumu, tikai pārliecinieties, ka tagi vienmēr ir aizpildīti un datus var saplēst.
Vienkārši</b><br><b>maize

Tādējādi pa daļām, kā vēlaties, varat nosūtīt liels fails uz hendleri.

Tagad apskatīsim, kā šie dati tiek apstrādāti un kā tos iegūt.

Sāksim ar sākuma tagu funkciju startElement ($parser, $name, $attrs)
Pieņemsim, ka apstrāde ir sasniegusi līniju
< ingredient amount = "3" unit = "стакан" >Milti
Tad funkcijas iekšpusē mainīgais $name būs vienāds ar sastāvdaļa tas ir, atvērtā taga nosaukums (tas vēl nav aizvērts).
Arī iekšā šajā gadījumā būs pieejams šī taga $attrs atribūtu masīvs, kurā būs ietverti dati daudzums = "3" un mērvienība = "stikls".

Pēc tam funkcija apstrādāja atvērtā taga datus dati ($parser, $data)
Mainīgais $data saturēs visu, kas atrodas starp sākuma un beigu tagiem, mūsu gadījumā tas ir teksts Muka

Un beidzas mūsu virknes apstrāde ar funkciju endElement ($parser, $name)
Šis ir slēgtā taga nosaukums, mūsu gadījumā $name būs vienāds ar sastāvdaļa

Un pēc tam atkal viss ritēja pa apli.

Iepriekš minētais piemērs parāda tikai XML apstrādes principu, bet reālai lietošanai tas ir jāmaina.
Parasti jums ir jāparsē liels XML, lai ievadītu datus datu bāzē, un, lai pareizi apstrādātu datus, jums jāzina, kuram atvērtajam tagam dati pieder, kādam tagu ligzdošanas līmenim un kuri tagi ir atvērti augstāk esošajā hierarhijā. Izmantojot šo informāciju, jūs varat pareizi apstrādāt failu bez problēmām.
Lai to izdarītu, jums ir jāievieš vairāki globāli mainīgie, kas apkopos informāciju par atvērtajiem tagiem, ligzdošanu un datiem.
Šeit ir piemērs, ko varat izmantot

Funkcija webi_xml ($file)
{
globāls $webi_depth ; // skaitītājs, lai izsekotu ligzdošanas dziļumu
$webi_depth = 0 ;
globālā $webi_tag_open ; // saturēs masīvu atvērtā in Šis brīdis tagus
$webi_tag_open = masīvs();
globālā $webi_data_temp ; // šajā masīvā būs viena taga dati

####################################################
### datu funkcija
funkciju dati ($parser, $data)
{
globāls $webi_depth ;
globālā $webi_tag_open ;
globālā $webi_data_temp ;
// pievienojiet masīvam datus, kas norāda uz ligzdošanu un pašlaik atvērto tagu
$webi_data_temp [ $webi_depth ][ $webi_tag_open [ $webi_depth ]][ "data" ].= $data ;
}
############################################

####################################################
### atvēršanas taga funkcija
funkcija startElement ($parser, $name, $attrs)
{
globāls $webi_depth ;
globālā $webi_tag_open ;
globālā $webi_data_temp ;

// ja ligzdošanas līmenis vairs nav nulle, tad viens tags jau ir atvērts
// un dati no tā jau ir masīvā, varat tos apstrādāt
ja ($webi_depth)
{




" ;

drukāt "
" ;
print_r($webi_tag_open); // atvērto tagu masīvs
drukāt "


" ;

// pēc datu apstrādes izdzēsiet tos, lai atbrīvotu atmiņu
unset($GLOBALS [ "webi_data_temp" ][ $webi_depth ]);
}

// tagad tiek atvērts nākamais tags, un turpmākā apstrāde tiks veikta nākamajā darbībā
$webi_depth++; // palielināt ligzdošanu

$webi_tag_open [ $webi_depth ]= $nosaukums ; // informācijas masīvam pievieno atvērtu tagu
$webi_data_temp [ $webi_depth ][ $name ][ "attrs" ]= $attrs ; // tagad pievienojiet tagu atribūtus

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

#################################################
## aizverošā taga funkcija
funkcija endElement ($parser, $name) (
globāls $webi_depth ;
globālā $webi_tag_open ;
globālā $webi_data_temp ;

// šeit sākas datu apstrāde, piemēram, pievienošana datu bāzei, saglabāšana failā utt.
// $webi_tag_open satur atvērtu tagu ķēdi pēc ligzdošanas līmeņa
// piemēram $webi_tag_open[$webi_depth] satur atvērtā taga nosaukumu, kura informācija pašlaik tiek apstrādāta
// $webi_depth tagu ligzdošanas līmenis
// $webi_data_temp[$webi_depth][$webi_tag_open[$webi_depth]]["attrs"] tagu atribūtu masīvs
// $webi_data_temp[$webi_depth][$webi_tag_open[$webi_depth]]["data"] taga dati

Drukāt "datus". $webi_tag_open [ $webi_depth]. "--" .($webi_data_temp [ $webi_depth ][ $webi_tag_open [ $webi_depth ]][ "data" ]). "
" ;
print_r ($webi_data_temp [ $webi_depth ][ $webi_tag_open [ $webi_depth ]][ "attrs" ]);
drukāt "
" ;
print_r($webi_tag_open);
drukāt "


" ;

Unset($GLOBALS [ "webi_data_temp"]); // pēc datu apstrādes mēs izdzēšam visu masīvu ar datiem, jo ​​tags tika aizvērts
unset($GLOBALS [ "webi_tag_open" ][ $webi_depth ]); // dzēst informāciju par šo atvērto tagu... kopš tā aizvēršanas

$webi_depth --; // samazināt ligzdošanu
}
############################################

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

// norāda, kuras funkcijas darbosies, atverot un aizverot tagus
xml_set_element_handler($xml_parser, "startElement", "endElement");

// norādiet funkciju darbam ar datiem
xml_set_character_data_handler($xml_parser, "dati");

// atveriet failu
$fp = fopen($fails, "r");

$perviy_vxod = 1 ; // karodziņš, lai pārbaudītu pirmo ierakstu failā
$dati = "" ; // šeit mēs apkopojam datus no faila pa daļām un nosūtām tos uz xml parsētāju

// cilpu, līdz tiek atrasts faila beigas
kamēr (! feof ($fp ) un $fp )
{
$simvol = fgetc ($fp); // nolasa vienu rakstzīmi no faila
$dati .= $simvol ; // pievieno šo rakstzīmi nosūtāmajiem datiem

// ja rakstzīme nav beigu tags, atgriezieties cilpas sākumā un pievienojiet datiem vēl vienu rakstzīmi un tā tālāk, līdz tiek atrasts beigu tags
if($simvol != ">" ) (turpināt;)
// ja tika atrasts noslēdzošais tags, tagad mēs nosūtīsim šos savāktos datus apstrādei

// pārbaudiet, vai šis ir pirmais ieraksts failā, tad mēs izdzēsīsim visu, kas atrodas pirms taga// jo dažreiz pirms XML sākuma varat saskarties ar atkritumiem (neveikli redaktori vai fails tika saņemts ar skriptu no cita servera)
if($perviy_vxod ) ( $data = strstr ($data , "

// tagad iemet datus xml parsētājā
if (! xml_parse ($xml_parser, $data, feof ($fp))) (

// šeit var apstrādāt un saņemt derīguma kļūdas...
// tiklīdz tiek konstatēta kļūda, parsēšana tiek pārtraukta
atbalss"
XML kļūda: " . xml_error_string(xml_get_error_code($xml_parser));
atbalss "pie līnijas" . xml_get_current_line_number ($xml_parser);
pārtraukums;
}

// pēc parsēšanas atmetiet apkopotos datus nākamajam cikla posmam.
$dati = "" ;
}
fclose($fp);
xml_parser_free($xml_parser);
// globālo mainīgo noņemšana
unset($GLOBALS [ "webi_depth"]);
unset($GLOBALS [ "webi_tag_open"]);
unset($GLOBALS [ "webi_data_temp"]);

Webi_xml("1.xml");

?>

Visam piemēram ir pievienoti komentāri, tagad pārbaudiet un eksperimentējiet.
Lūdzu, ņemiet vērā, ka, strādājot ar datiem, dati netiek vienkārši ievietoti masīvā, bet gan pievienoti, izmantojot " .=" jo dati var nesanākt pilnībā, un, ja jūs vienkārši veicat uzdevumu, tad laiku pa laikam jūs saņemsit datus pa daļām.

Tas arī viss, tagad ir pietiekami daudz atmiņas, apstrādājot jebkura izmēra failu, taču skripta darbības laiku var palielināt vairākos veidos.
Ievietojiet funkciju skripta sākumā
set_time_limit(6000);
vai
ini_set ("maksimālais_izpildes_laiks" , "6000");

Vai pievienojiet tekstu .htaccess failam
php_value max_execution_time 6000

Šie piemēri palielinās skripta darbības laiku līdz 6000 sekundēm.
Šādā veidā laiku var palielināt tikai tad, ja drošais režīms ir izslēgts.

Ja jums ir piekļuve php.ini rediģēšanai, varat palielināt laiku, izmantojot
maksimālais_izpildes_laiks = 6000

Piemēram, Masterhost hostingā šī raksta rakstīšanas laikā skripta laika pagarināšana ir aizliegta, neskatoties uz to drošais režīms, bet, ja esat profesionālis, varat izveidot savu php, izmantojot masterhost, taču tas nav norādīts šajā rakstā.

XML parsēšana būtībā nozīmē iziet cauri XML dokumentam un atgriezt atbilstošos datus. Un, lai gan arvien vairāk tīmekļa pakalpojumu atgriež datus uz JSON formāts bet lielākā daļa joprojām izmanto XML, tāpēc ir svarīgi apgūt XML parsēšanu, ja vēlaties izmantot visu diapazonu pieejamās saskarnes API.

Izmantojot paplašinājumu SimpleXML PHP, kas tika pievienots atpakaļ PHP 5.0, strādāt ar XML ir ļoti viegli un vienkārši. Šajā rakstā es jums parādīšu, kā to izdarīt.

Lietošanas pamati

Sāksim ar šādu piemēru valodas.xml:


>

> 1972>
> Deniss Ričijs >
>

> 1995>
> Rasmuss Lerdorfs >
>

> 1995>
> Džeimss Goslings >
>
>

Šajā XML dokumentā ir iekļauts programmēšanas valodu saraksts ar informāciju par katru valodu: tā ieviešanas gads un tā veidotāja vārds.

Pirmais solis ir ielādēt XML, izmantojot vai nu funkcijas simplexml_load_file(), vai simplexml_load_string(). Kā norāda funkciju nosaukums, pirmā ielādēs XML no faila, bet otrā ielādēs XML no virknes.

Abas funkcijas nolasa visu DOM koku atmiņā un atgriež objektu SimpleXMLElement. Iepriekš minētajā piemērā objekts tiek saglabāts mainīgajā $languages. Varat izmantot funkcijas var_dump() vai print_r() lai saņemtu sīkāku informāciju par atgriezto objektu, ja vēlaties.

SimpleXMLElement objekts
[lang] => Masīvs
[0] => SimpleXMLElement objekts
[@attributes] => Masīvs
[vārds] => C
[parādījās] => 1972. gads
[radītājs] => Deniss Ričijs
[1] => SimpleXMLElement objekts
[@attributes] => Masīvs
[vārds] => PHP
[parādījās] => 1995. gads
[radītājs] => Rasmuss Lerdorfs
[2] => SimpleXMLElement objekts
[@attributes] => Masīvs
[vārds] => Java
[parādījās] => 1995. gads
[radītājs] => Džeimss Goslings
)
)

Šis XML satur saknes elementu valodas, kura iekšpusē ir trīs elementi lang. Katrs masīva elements atbilst elementam lang XML dokumentā.

Izmantojot operatoru, varat piekļūt objekta īpašībām -> . Piemēram, $languages->lang atgriezīs SimpleXMLElement objektu, kas atbilst pirmajam elementam lang. Šis objekts satur divus rekvizītus: parādījās un veidotājs.

$languages ​​​​-> lang [ 0 ] -> parādījās ;
$languages ​​​​-> lang [0] -> veidotājs;

Valodu saraksta parādīšanu un to rekvizītu parādīšanu var veikt ļoti vienkārši, izmantojot standarta cilpu, piemēram, katram.

foreach ($languages ​​​​-> lang kā $lang ) (
printf(
"" ,
$lang ["vārds"],
parādījās $lang -> ,
$lang -> veidotājs
) ;
}

Ievērojiet, kā es piekļuvu elementa lang atribūta nosaukumam, lai iegūtu valodas nosaukumu. Tādā veidā jūs varat piekļūt jebkuram elementa atribūtam, kas attēlots kā SimpleXMLElement objekts.

Darbs ar nosaukumu telpām

Strādājot ar dažādu tīmekļa pakalpojumu XML, elementu nosaukumvietām nāksies saskarties vairāk nekā vienu reizi. Mainīsim savu valodas.xml lai parādītu nosaukumvietas izmantošanas piemēru:



xmlns:dc =>

> 1972>
> Deniss Ričijs >
>

> 1995>
> Rasmuss Lerdorfs >
>

> 1995>
> Džeimss Goslings >
>
>

Tagad elements radītājs iederas nosaukumvietā dc kas norāda uz http://purl.org/dc/elements/1.1/. Ja mēģināsit izdrukāt valodas veidotājus, izmantojot mūsu iepriekšējo kodu, tas nedarbosies. Lai lasītu elementu nosaukumvietas, jums jāizmanto viena no tālāk norādītajām pieejām.

Pirmā pieeja ir izmantot URI nosaukumus tieši kodā, piekļūstot elementa nosaukumvietai. Šis piemērs parāda, kā tas tiek darīts:

$dc = $languages ​​​​-> lang [1] -> children( "http://purl.org/dc/elements/1.1/") ;
echo $dc -> veidotājs ;

Metode bērni () aizņem nosaukumvietu un atgriež pakārtotos elementus, kas sākas ar prefiksu. Tam nepieciešami divi argumenti, no kuriem pirmais ir XML nosaukumvieta, bet otrs ir neobligāts arguments, kas pēc noklusējuma ir viltus. Ja otrais arguments ir iestatīts uz TRUE, nosaukumvieta tiks uzskatīta par prefiksu. Ja FALSE, tad nosaukumvieta tiks uzskatīta par URL nosaukumvietu.

Otrā pieeja ir nolasīt URI nosaukumus no dokumenta un izmantot tos, piekļūstot elementu nosaukumvietai. Tas faktiski ir labāks veids, kā piekļūt elementiem, jo ​​jums nav jābūt URI kodētam.

$namespaces = $languages ​​​​-> getNamespaces (true) ;
$dc = $languages ​​​​-> lang [1] -> bērni (($namespaces [ "dc" ] ) ;

echo $dc -> veidotājs ;

Metode GetNamespaces() atgriež prefiksu nosaukumu masīvu un ar tiem saistītos URI. Tas pieņem papildu parametru, kas tiek iestatīts pēc noklusējuma viltus. Ja iestatāt kā taisnība, tad šī metode atgriezīs vecāku un bērnmezglos izmantotos nosaukumus. Pretējā gadījumā tas atrod nosaukumvietas, kas tiek izmantotas tikai vecākmezglā.

Tagad jūs varat atkārtot šādu valodu sarakstu:

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

foreach ($languages ​​​​-> lang kā $lang ) (
$dc = $lang -> bērni ($ns [ "dc" ] ) ;
printf(
"

%s parādījās %d, un to izveidoja %s .

" ,
$lang ["vārds"],
parādījās $lang -> ,
$dc -> veidotājs
) ;
}

Praktisks piemērs — YouTube video kanāla parsēšana

Apskatīsim piemēru, kas iegūst RSS plūsmu no YouTube kanāla un parāda saites uz visiem tā videoklipiem. Lai to izdarītu, lūdzu, sazinieties ar šo adresi:

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

URL atgriež sarakstu ar jaunākajiem videoklipiem no konkrētā kanāla XML formātā. Mēs parsēsim XML un iegūsim šādu informāciju par katru videoklipu:

  • Saite uz video
  • Miniatūra
  • Vārds

Sāksim ar XML meklēšanu un ielādi:

$channel = "Kanāla_nosaukums" ;
$url = "http://gdata.youtube.com/feeds/api/users/". $kanāls. "/augšupielādes" ;
$xml = fails_get_contents($url);

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

Ja paskatās uz XML plūsmu, jūs varat redzēt, ka tajā ir vairāki elementi entītija, katrs no kuriem veikali Detalizēta informācija par konkrētu videoklipu no kanāla. Taču mēs izmantojam tikai attēlu sīktēlus, video URL un nosaukumu. Šie trīs elementi ir elementa pēcteči grupai, kas savukārt ir bērns no ierakstu:

>

>



Nosaukums… >

>

>

Mēs vienkārši iziesim cauri visiem elementiem ierakstu, un par katru no tiem mēs izvilksim nepieciešamo informāciju. pieraksti to spēlētājs sīktēls Un virsraksts atrodas multivides nosaukumvietā. Tādējādi mums ir jārīkojas tāpat kā iepriekšējā piemērā. Mēs iegūstam nosaukumus no dokumenta un izmantojam nosaukumvietu, piekļūstot elementiem.

foreach ($feed -> ieraksts kā $entry ) (
$grupa = $entry -> bērni ($ns [ "media" ] ) ;
$grupa = $grupa -> grupa ;
$thumbnail_attrs = $grupa -> sīktēls [ 1 ] -> atribūti () ;
$image = $thumbnail_attrs [ "url"];
$spēlētājs = $grupa -> spēlētājs -> atribūti () ;
$saite = $player [ "url"] ;
$nosaukums = $grupa -> nosaukums ;
printf( "

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

Secinājums

Tagad, kad jūs zināt, kā izmantot SimpleXML XML datu parsēšanai varat uzlabot savas prasmes, parsējot dažādas XML plūsmas ar dažādām API. Taču ir svarīgi ņemt vērā, ka SimpleXML nolasa visu DOM atmiņā, tāpēc, ja parsējat lielu datu kopu, var pietrūkt atmiņas. Lai uzzinātu vairāk par SimpleXML, izlasiet dokumentāciju.


Ja jums ir kādi jautājumi, iesakām izmantot mūsu