misterjinx™

DOM vs. SimpleXML partea 2

Posted by: misterjinx on: noiembrie 2, 2008

Ca urmare a ultimului articol, voi continua acum descrierea modalităţilor de lucru cu xml din php. De această dată este vorba de DOM.

Parserele de tip DOM construiesc în memorie întregul arbore de resurse. Acesta poate fi ulterior parcurs, şters, modificat, adăugat. Un avantaj al DOM constă în flexibilitatea mai mare oferită faţă de SimpleXML, cu preţul unei complexităţi sporite.

Extensia DOM (specifică php5) este exclusiv orientată pe obiecte. Principala clasă este DOMNode, din care derivă DOMDocument, DOMElement, DOMAttr, DOMComment, DOMText. Celelalte două clase disponibile sunt DOMNodeList şi DOMXPath.

Încărcarea codului xml se poate face din fişier sau string, prin instanţierea unui obiect de tip DOMDocument urmat de apelarea metodelor de încărcare: load şi loadHTMLFile (din fişier), respectiv loadHTML şi loadXML (din string).

$xml = new DOMDocument();

$xml->load(“fisier.xml”);

$xml->load(“http://adresa_web/fisier.xml”);

$string = file_get_contents(“fisier.xml”);

$xml->loadXML($string);

Parcurgerea unui arbore de tip DOM şi accesul la resurse se face printr-o multitudine de metode şi câmpuri puse la dispoziţie de toate clasele DOM. Lista lor este foarte mare şi de aceea voi menţiona doar câteva, cele mai importante.

Să luăm drept exemplu acelaşi fişier ca şi în prima parte a articolului:

<?xml version=”1.0″?>

<unitati>

<server tip=”pc” memorie=”1gb” hdd=”100gb”>

<nume>unitatea 0</nume>

</server>

<calculator tip=”pc” memorie=”2gb” hdd=”160gb”>

<nume>unitatea 1</nume>

<valoare>1500 lei</valoare>

</calculator>

<calculator tip=”pc” memorie=”1gb” hdd=”100gb”>

<nume>unitatea 2</nume>

<valoare>1200 lei</valoare>

</calculator>

<calculator tip=”mac” memorie=”2gb” hdd=”120gb”>

<nume>unitatea 3</nume>

<valoare>3500 lei</valoare>

</calculator>

</unitati>

Parcurgerea acestui fişier se poate face în felul următor:

$xml = new DOMDocument();

$xml->load(“fisier_de_mai_sus.xml”);

echo $xml->nodeName; // afiseaza #document

echo $xml->firstChild->nodeName; // afiseaza unitati

echo $xml->firstChild->firstChild->nodeName; // afiseaza server

foreach ( $xml->firstChild->childNodes as $s) echo $s->nodeName . ” “; // afiseaza server calculator calculator calculator

foreach ( $xml->DocumentElement as $nod )

{

echo $nod->nodeName;

if ( $nod->hasAttributes() )

{

foreach ( $nod->attributes as $a )

{

echo $a->name . “: ” . $a->value . “<br/>”; //afiseaza nume_atribut: valoare_atribut

}

}

echo “<br/>”;

}

Bun, acum să luăm pe rând să vedem ce am folosit mai sus pentru parsarea fişierului.

  • Câmpul nodeName din clasa DOMNode afişează numele nodului. Pentru elemente returnează numele tagului, iar pentru noduri text #text.
  • Câmpul firstChild ( sau lastChild ) desemnează primul/ultimul nod copil al nodului curent
  • childNodes returnează lista de noduri copil
  • documentElement returnează elementul rădăcină al fişierului xml
  • metoda hasAttributes returnează true/false dacă elementul are atribute sau nu
  • Câmpul attributes returnează lista de atribute ale unui nod, sub forma unui obiect iterabil. pentru afisarea lor se folosesc câmpurile clasei DOMAttr, name şi value.

De asemenea se pot adăuga noduri la obiectul curent prin metodele clasei DOMNode, appendChild sau insertBefore, iar asocierea de atribute se poate face prin metoda setAttribute, a clasei DOMElement.

Dacă dorim, putem crea de la zero un document xml folosind metoda createElement a clasei DOMDocument, pentru crearea de elemente, createAttribute, pentru adăugare de atribute şi createTextNode, pentru adăugarea de PCDATA.

Spuneam la început că se pot folosi şi interogări XPath pentru parcurgerea codului XML. Clasa care ajută la acest lucru este DOMXPath. Prinicipala metodă a acestei clase este query, care primeşte ca argument expresia XPath şi returnează nodurile găsite sub forma unui obiect de tip DOMNodeList ce se poate itera.

Extensia DOM este foarte puternică pentru lucrul cu fişiere XML şi din acest motiv, foarte complexă. Dacă doriţi să cunoaşteţi mai multe desprea ea puteţi să începeţi cu documentaţia de pe site-ul oficial.

Etichete , , ,

DOM vs. SimpleXML partea 1

Posted by: misterjinx on: octombrie 25, 2008

Pentru lucrul cu XML există 2 extensii disponibile în PHP, SimpleXML şi DOM. În următoarele 2 articole voi vorbi pe rând despre fiecare dintre ele, iar la final voi scrie nişte avantaje şi dezavantaje pentru fiecare.

SimpleXML

După cum spune şi numele, extensia SimpleXML este intuitivă şi uşor de învăţat. Ea a fost dezvoltată ca o soluţie intermediară între DOM şi SAX: are un consum de resurse mic, precum SAX, însă nu este aşa de flexibilă, precum DOM.

SimpleXML prezintă funcţii ce permit încărcarea de cod XML din fişiere, string-uri sau noduri DOM.

//încarcare din fişier

$xml = simple_xml_load_file(“fisier_sursa.xml”);

//încarcare din string

$string = file_get_contents(“fisier_sursa.xml”);

$xml = simplexml_load_string($string);

De asemenea acest lucru se poate realiza şi prin utilizarea clasei SimpleXMLElement (principala clasă a SimpleXML):

$xml = new SimpleXMLElement(“fisier_sursa.xml”, null, true);

După încărcarea codului XML, conţinutul poate fi parcurs foarte uşor folosind membrii clasei SimpleXMLElement.

Să presupunem că fişierul sursă invocat mai sus are următorul conţinut:

<?xml version=”1.0″?>

<unitati>

<server tip=”pc” memorie=”1gb” hdd=”100gb”>

<nume>unitatea 0</nume>

</server>

<calculator tip=”pc” memorie=”2gb” hdd=”160gb”>

<nume>unitatea 1</nume>

<valoare>1500 lei</valoare>

</calculator>

<calculator tip=”pc” memorie=”1gb” hdd=”100gb”>

<nume>unitatea 2</nume>

<valoare>1200 lei</valoare>

</calculator><calculator tip=”mac” memorie=”2gb” hdd=”120gb”>

<nume>unitatea 3</nume>

<valoare>3500 lei</valoare>

</calculator>

</unitati>

Un obiect de tip SimpleXMLElement corespunde fiecarui element din XML, în cazul de mai sus fiind chiar elementul rădăcină. Pentru aflarea numelui se foloseşte metoda getName().

echo $xml->getName(); // va afişa unitati

În cazul acestei extensii sub-elementele sunt tratate precum câmpuri ale obiectului definit, fiecare element copil având un câmp cu numele său.

$server = $xml->server; // $c devine un obiect SimpleXMLElement

echo $server->nume; // va afisa unitatea 0

În cazul în care există mai multe sub-elemente cu acelaşi nume, ele vor fi construite ca un array şi se vor putea apela asemeni acestora.

$calculatoare = $xml->calculator; //preiau toate sub-elementele calculator

foreach ( $calculatoare as $calculator ) echo $calculator->nume; //va afişa pe rând fiecare numele

Conţinutul PCDATA se poate obţine prin conversia la string a unui obiect SimpleXMLElement.

echo $server->nume; // va afisa unitatea 0

Atributele fiecărui element se pot accesa sub forma unui tablou asociativ, având forma elementului căruia aparţin.

echo $server['tip']; //va afişa pc

De asemenea pentru atributele unui element se mai poate folosi şi metoda attributes(), care extrage atributele sub forma unui tablou asociativ de obiecte de tip SimpleXMLElement.
Pe scurt, cam aşa se prezintă extensia SimpleXML. După cum spuneam la început, este foarte intuitivă şi uşor de învăţat. Pentru a nu lungi însa prea mult acest post voi vorbi despre cealaltă extensie pentru lucrul cu fişiere xml în următorul articol.

Etichete , , ,

Webstock 2008

Posted by: misterjinx on: octombrie 3, 2008

Azi am dat şi eu o raită pe la webstock, mai pe seară, pentru a asista la decernarea premiilor. Mi s-au părut ok alegerile, mai puţin locul 2 obţinut de 360creative la categoria la care erau înscrişi. Mi se pare de prost gust ce au făcut ei cu site-ul lor, având în vedere că habar au de web.

Organizarea a fost mişto, sponsorii pe măsură, unele premii la fel :D . Să vedem cum va fi la internetics acum.

Etichete

Preluarea cursului BNR în mai puţin de 10 linii de cod

Posted by: misterjinx on: septembrie 25, 2008

Azi am fost nevoit să preiau cursul valutar de pe site-ul bnr pentru a-l stoca în baza de date.  Ştiu că erau pe nu ştiu ce site-uri puse la dispoziţie coduri care fac treaba asta, însă după mine într-o manieră foarte alandala. După mine cel mai simplu de parsat un fişier xml (cum este cel pus la dispoziţie de bnr) este folosind extensiile puse la dispoziţie de php, SimpleXML şi DOM. Eu am ales să folosesc DOM, deoarece rezolvă foarte repede ceea ce am avut nevoie.

Structura fişierului xml care trebuie parsat este urătoarea:

<DataSet xsi:schemaLocation=”http://www.bnr.ro/xsd nbrfxrates.xsd”>
<Header>
<Sender>National Bank of Romania</Sender>
<SendingDate>2008-09-25</SendingDate>
<MessageType>DR</MessageType>
</Header>
<Body>
<Subject>Reference rates</Subject>
<OrigCurrency>RON</OrigCurrency>
<Cube date=”2008-09-25″>
<Rate currency=”AUD”>2.0985</Rate>
<Rate currency=”BGN”>1.8802</Rate>
<Rate currency=”CAD”>2.4202</Rate>
<Rate currency=”CHF”>2.3059</Rate>
<Rate currency=”CZK”>0.1505</Rate>
<Rate currency=”DKK”>0.4930</Rate>
<Rate currency=”EGP”>0.4583</Rate>
<Rate currency=”EUR”>3.6773</Rate>
<Rate currency=”GBP”>4.6475</Rate>
<Rate currency=”HUF” multiplier=”100″>1.5275</Rate>
<Rate currency=”JPY” multiplier=”100″>2.3608</Rate>
<Rate currency=”MDL”>0.2414</Rate>
<Rate currency=”NOK”>0.4452</Rate>
<Rate currency=”PLN”>1.1040</Rate>
<Rate currency=”RUB”>0.1000</Rate>
<Rate currency=”SEK”>0.3800</Rate>
<Rate currency=”SKK”>0.1214</Rate>
<Rate currency=”TRY”>2.0194</Rate>
<Rate currency=”USD”>2.5001</Rate>
<Rate currency=”XAU”>71.4560</Rate>
<Rate currency=”XDR”>3.9396</Rate>
</Cube>
</Body>
</DataSet>

(evident documentul nu este valid, dar nu ne interesează asta :P )

După cum se observă, ce trebuie noi să facem este preluarea tuturor tagurilor cu numele „Rate”.  Apoi preluăm  numele valutei folosind metoda getAttribute, care returnează valoarea atributului cu numele specificat.

Iată codul care pune în aplicare cele spuse mai sus:

/*
* initiez clasa DOMDocument, reprezentand fisierul xml incarcat
*/
$dom = new DOMDocument();
/*
* incarc fisierul xml, specificand adresa completa
*/
$dom->load( “http://www.bnro.ro/nbrfxrates.xml” );

/*
* preiau intr-un obiect iterabil lista elementelor(tagurile) cu numele specificat
*/
$valute = $dom->getElementsByTagName(‘Rate’);

/*
* verific daca sunt elemente de acest tip
*/
if ( $valute->length != 0 )
{
/*

* in caz afirmativ, iterez prin ele si le afiez

* ( evident le pot stoca intr-un array sau chiar in baza de date,

* dupa caz)
*/
foreach ( $valute as $valuta )
{
echo $valuta->getAttribute(currency). ” – ” .$valuta->nodeValue . “<br/>”;
}
}

Dacă nu punem la socoteală, liniile comentate, putem prelua codul bnr în doar 8 linii de cod ! În acelaşi mod se pot prelua şi diferite feed-uri de pe diverse site-uri. Baftă ;)

Editorul perfect

Posted by: misterjinx on: septembrie 20, 2008

Pentru mine editorul perfect ar trebui să aibă următoarele caracteristici:

  • syntax highlight
  • inteligent automatic brace/square brackets/parenthesis and single/double quotes closing
  • file explorer
  • brace/parentheses block highlight
  • phpDoc support
  • ftp support

şi cam atât. Cer prea mult? Nu cred. Singurul care s-ar apropia de cerinţele acestea ar fi Eclipse (pdt) însă este IDE (!!!) şi nu are nici suport ftp.

Eu nu ştiu un asemenea editor. Voi aveţi vreo idee?

Etichete