Acest subcapitol va prezenta succint modalitatile de procesare a datelor XML prin intermediul JavaScript. Vom presupune cunoscute conceptele de baza ale metalimbajului XML (
Extensible Markup Language)-cititorul interesat si/sau curios are la dispozitie lucrerea semnata de Sabin Buraga,
Tehnologii XML,aparuta la Editura Polirom,Iasi,in 2006.
1. Prelucrari XML prin DOM Cum majoritatea programelor JavaScript vor rula in mediul de executie reprezentat de browserul Web,modelul de procesare XML va fi DOM(
Document Object Model).Reamintim faptul ca datele XML sunt reprezentate intern sub forma unui arbore avand noduri de diverse tipuri(elemente,atribute,continuturi textuale,comentarii etc.).Accesul la noduri si eventual alterarea lor se vor realiza via proprietati si metode puse la dispozitie de obiecte construite de navigator pe baza interfetei de programare-API(
Application Programming Interface)-DOM standarizate de Consortiul Web.
Accesul la nodul radacina al documentului Web va fi oferit de proprietatea ‚documentElement’ atasata obiectului ‚document’ predefinit.
Pentru parcurgerea arborelui,metodele si proprietatile frecvent folosite sunt urmatoarele:
-getElementById (
identificator)-furnizeaza un element conform identificatorul sau unic,desemnat de valoarea atributului id specificat in cadrul documentului;
-getElementsByTagName (
numeTag)-intoarce o lista a tuturor elementelor XML desemnate de
numeTag.Aceasta lista este reprezentata in JavaScript ca un tablou;
-parentNode-proprietate care ofera accesul la numele nodului-parinte al nodului curent;
-childNodes-proprietate ce furnizeaza intr-un tablou numele nodurilor-copil ale nodului curent;
-firstChild-proprietate desemnand primul nod-copil;
-lastChild-proprietate specificand ultimul nod-copil;
-attributes-pentru un nod de tip element,reprezinta tabloul continand atributele asociate elementului in cauza.
Diverse informatii referitoare la noduri pot fi obtinute prin intermediul urmatoarelor proprietati si metode:
-nodeType-furnizeaza tipul unui nod(de exemplu, 1 = element, 2 = atribut, 3 = continut text);
-nodeValue-proprietate care ofera valoarea unui nod;
-innerHTML-proprietate furnizand codul (x) HTML dintr-un element;de asemenea,se permite alterarea valorii ei;
-getAttributes()-returneaza o valoare booleana determinand daca un nod de tip ‚element’ are sau nu atribute;
-getAttribute(
nume atribut)-metoda care acceseaza un atribut.
Pentru modificarea structurii arborelui DOM,avem la dispozitie metode precum:
-createElement(
element )-creeaza un nod de tip ‚element’;
-appendChild(
nod)-adauga un nod-copil nodului curent;
-removeChild(
nod)-elimina un nod-copil;
-cloneNode()-‚cloneaza’ un nod al arborelui;
-setAttribute(
atribut,valoarea)-stabileste valoarea unui atribut dat.
Ca exemplu de procesare HTML,vom prezenta urmatorul fragment de cod.Folsim o functie JavaScript anonima care va genera un tablou avand drept valori lungimea sirurilor de caractere corespunzatoare nodurilor de tip text din arborele DOM cu radacina precizata de obiectul element:
Var continut = (function(element) {
If (element.nodeType ==3) { // nod text (din DOM)
// tablou cu un singur membru
return [element.nodeValue.lenght];
}
var elemente = new Array();
// recursiv,adaugam in tabloul ‚elemente’
// informatii preluate din nodul-copil
// al arborelui DOM cu radacina ‚element’
for ( var i = 0, copil;
copil = element.childNodes[i]; i++) {
elemente.push (arguments.callee (copil));
}
return elemente;// returnam tabloul creat
}) (document.documentElement);
Functia se apeleaza recursiv pentru fiecare nod copil al elementului curent-pentru aceasta folosim ‚callee’.
Dupa parcurgerea intregului document,tabloul ‚continut’ va stoca lungimea sirurilor de caractere ale fiecarui nod de tip text.Vom converti acest tablou in sir de caractere si vom inlocui virgulele,delimitand fiecare element al sau cu spatiu,Acesta se poate realiza cu o constructie de forma continut.toString().replace(/,/g,” ”),apeland la o expresie regulata.
Informatiile vor fi inserate in pagina Web,intr-un element <
div> identificat prin
id=”rezultat”.
Astfel,tot ce mai trebuie sa scriem este codul urmator:
//obtinem <div>-ul dorit
var rezultat = document.getElementById(”rezultat”);
//…si inseram elementele tabloului
rezultat.innerHTML =
continut,toString() .replace(/,/g,” ”);
Documentul XHTML care va apela liniile JavaScript-incapsulate intr-o functie denumita
afisare() si executata la incarcarea paginii-poate avea structura urmatoare:
<body onload=”javascript:afisare()”>
<u1>
<l1><p>Web</p></li>
<l1><p>2.0</p></li>
</u1>
<div id=”rezultat” />
</body>
O a doua exemplificare ilustreaza maniera de generare de marcaje XHTML-adaptare dupa un exemplu furnizat de specificatia E4X:
Function genereazaTabel() {
Const DIM = 5; // dimensiunea tabelului
// vom insera tabelul generat
// la inceputul paginii Web
var corp = document.getElementsByTagName(
”body”).item(0);
//cream tabelul
tabel = document.createElement(”table”);
corpTabel = document.createElement(”tbody”);
// generam si liniile de tabel…
for (var rand = 0; rand < DIM; rand++) {
randCurent = document.createElement(”tr”);
for (var coloana = 0; coloana < DIM; coloana++) {
//…inclusiv continutul celulelor
celula = document.createElement(”td”);
continut = document.createTextNode(
”textul din linia” + rand +
” si coloana ” + coloana;
celula.appendChild(continut);
randCurent.appendChild(celula);
}
corpTabel.appendChild(randCurent);
}
tabel.appendChild(corpTabel);
corp.appendChild(tabel);
//stabilim un chenar pentru tabel
tabel.setAttribute(”border”,”2”);
2. Evenimente Un eveniment reprezinta o actiune produsa in cadrul mediului de executie in urma careia scriptul va putea reactiona intr-o anumita maniera.Uzual,codul JavaScript rulat la aparitia unui eveniment va fi incapsulat intr-o functie de tratare a acestuia.
Modul traditional de tratare a evenimentelor se bazeaza pe atasarea de cod JavaScript ce va fi executat la aparitia unui eveniment de baza-precum „onclick”, „onmouseover”, „onchange”, „onload”- asupra unui element.Pentru exemplificari,revedeti o parte dintre fragmentele de cod prezentate anterior.
Mecanismul de tratar a evenimentelor a fost standardizat de specificatia DOM Events-:http//www.w3.org/TR/DOM-level-2-Events/,Conform acesteia,evenimentele sunt grupate in categorii:
-evenimente realizate in urma interactiunii cu utilizatorul(apasarea unei taste sau a unui buton al mouse-ului,miscarea cursorului mouse-ului,parasirea unui formular Web,etc.);
-evenimente referitoare la starea paginii(de exemplu incarcarea sau parasirea ei);
-evenimente referitoare la modificari de structura a documentului XHTML(adaugarea unui element,modificarea valorii unui atribut,stergerea unui nod,etc.).
Asocierea unei functii de tratare unui eveniment se poate realiza printr-o olinie de forma:
Document.getElementById(”identificator”).onclick = trateazaClick;
Functia de tratare va primica unic argument o instanta de tip event:
Function trateazaClick(eveniment)
{
alert („a aparut un click:”+eveniment);
// alertam utilizatorul asupra aparitiei evenimentului
}
Modalitatea standard de atasare a unei functii de tratare unui anumit eveniment este cea folosind metoda addEventListener ():
Obiect.addEventListener(„eveniment”, functie, mod);
Modul de invocare a functiei depinde de valoarea booleana a parametrului
mod. Pentru
mod cu valoare
true,se va incerca tratarea evenimentului pornind de la evenimentul radacina pana la obiectul tinta- acest comportament se numeste ‚capture phase’ si este respectat de vechiul navigator Netscape.Daca
mod are valoarea
false,atunci evenimentul este propagat in sens invers-procesul se numeste ‚bubbling phase’ si apare la Internet Explorer.
Drept exemplu mentionam:
Document.getElementById(”text”).addEventListener(
”mouseover”, schimbaFront, true);
Pentru a elimina tratamentul unui eveniment,vom recurge la metoda removeEventListener() care prezinta aceleasi argumente ca addEventListener().
Obiectul Event are atasate urmatoarele proprietati utile:
_type-specifica tipul evenimentului ca sir de caractere;
-cancelable-precizeaza daca evenimentul poate fi intrerupt;
-currentTarget-indica nodul care trateaza evenimentul
-target-desemneaza nodul asupra caruia evenimentul a fost initial declansat.
Evenimentele privind actiunile mouse-ului sunt click, mousedown, mouseup, mouseover,mousemove si mouseout.Pentru acest tip de evenimente, sunt disponibile anumite proprieteati aditionale,dintre care amintim:
-button-precizeaza ce buton al mouse-ului a fost utilizat (0 = cel stang,1 = median, 2 = cel drept)
-detail-indica de cate ori a fost apasat butonul;
-clientX-desemneaza coordonata orizontala a pozitiei mouse-ului,relativ la zona de afisare;
clientY-similar proprietatii precedente,dar pentru coordonata verticala.
Evenimente vizand tastatura sunt keyup,keydown si keypress.Si in acest caz vor putea fi folosite proprietati suplimentare,utile pentru a determina ce tasta a fost apasata(charCode si keyCode),eventual in combinatie cu tastele specifice.
In ceea ce priveste evenimentele referitoare la interactiunea cu browserul,mentionam load,unload,select,change,submit,focus,blur,resize si scroll.
Din nefericire,Internet Explorer nu implementeaza modelul DOM referitor la evenimente.Tinand cont de aceasta situatie,pentru Internet Explorer vom recurge la metoda attachEvent ():
Element.attachEvent(”eveniment”, functie);
Toate celelalte navigatoare au suport pentru DOM Events
3. AJAX in contextul JavaScript Suita de tehnologii AJAX
(Asynchronous JavaScript And XML) reprezinta una dintre componentele-cheie ale aplicatilor Web 2.0. Succesul acestora este asigurat de posibilitatea programatorilor de a realiza transferuri de date desfasurate asincron intre programele existente pe server si codul-client. Avantajele importante aduse de AJAX sunt cele privind eliminarea reincarcarii paginilor Web, facilitarea interactiunii cu utiIizatorul, micsorarea timpilor morti si altele.
Daca la nivel de server putem folosi diverse tehnologii/paradigme, pentru client avem la dispozitie doar executia de scripturi JavaScript. Astfel, o aplicatie care necesita AJAX va depinde de suportul oferit de catre browserul utilizat de vizitator.
Obiectul XMLHttpRequest Realizarea transferurilor de date dintre client si server este in responsabilitatea obiectului
XMLHttpRequest-componenta de baza AJAX. Acest obiect este pus la dispozitie practic de orice browser Web actual si permite realizarea de cereri HTTP
(e.g., GET si POST) dintr-un script ruland la nivel de client - uzual, navigatorul Web - spre o aplicape de pe server, intr-un mod asincron.
Datele vehiculate intre programele client si server pot fi stocate ca documente XML, HTML, JSON
(JavaScript Object Notation) sau CSV
(Comma Separated Values). JSON reprezinta un subset al limbajului JavaScript, avantajul fiind ca datele reprezentate in JSON sunt simple siruri de caractere ce pot fi convertite usor in (tablouri de) obiecte JavaScript.Astfel, dispare necesitatea procesarii continutului XML obtinut de la server. Pentru amanunte referitoare la formatul JSON, puteti consuIta situl
http://json.org/ Metodele pe care le vom folosi efectiv in contextul AJAX sunt:
·
open ( ) realizeaza deschiderea unei conexiuni HTTP cu serverul Web, trimitand o cerere (uzual, GET sau POST) catre acesta; aplicatia de pe server cu care va avea loc schimbul de date va fi desemnata de un URI, dupa cum vom vedea mai jos;
·
send ( ) transmite date - de cele mai multe ori, in maniera asincrona catre aplicatie ruland pe server;
·
abort ( ) abandoneaza transferul curent
·
setRequestHeader ( ) specifica diverse campuri ale antetuIui HTTP –de exemplu, se poate stabili o anumita valoare particulara pentru campul
Content-Type, aspect util atunci cand dorim sa manipulam alte tipuri de continuturi, JSON ori CSV.
In continuare furnizam cele mai importante proprietati ale obiectului
XMLHttpRequest:·
readyState furnizeza codul de stare a transferului – astfel, valoarea 4 indica faptul ca transferul datelor s-a efectuat complet;
·
status reprezinta codul de stare HTTP intors de serverul Web- de exemplu , 200(Ok), 404(Not Found), 500(Server Internal Error) etc.
·
onreadystatechange specifica functia invocata la modificarile de stare a transferului datelor. Deoarece datele sunt transmise in maniera asincrona,programul de la nivel de client trebuie sa poata fi notificat asupra evenimentelor care pot surveni pe parcursul transferului
·
responseXML desemneaza raspunsul receptionat de la server, datele fiind reprezentate ca document XML.
Instantierea obiectului
XMLHttpRequest este ilustrata de codul de mai jos:
//initializeaza obiectul XMLHttpRequest
function initializare ( ) {
if (window.XMLHttpRequest) {
// este implementat nativ
return new XMLHttpRequest( );
} else
if (window.ActiveXObject) {
// exista ca o componeneta ActiveX
//(la Internet Explorer)
return new ActiveXObject(“Microsof.XMLHTTP”);
} else {
// nu este disponibil
return null;
}
}
Pentru atasarea unei functii de tratare a schimbarii de stare a transferului,vom recurge la urmatoarele linii:
// proceseaza raspunsul (datele primite)
function procesareRaspuns ( ) {
// transferul s-a efectuat complet
// si am obtinut succes: 200 (Ok)
if (http.readyState = = 4 && http.status = = 200) {
var rezultat = http.responseText;
// procesarea datelor obtinute
// poate fi folosita si proprietatea responseXML
}
}
Formularea unei cereri adresate serverului Web este in responsabilitatea functiei de mai jos - in acest caz, folosim metoda
POST pentru a trimite anumite date spre aplicatia care ruleaza pe server:
function expediereCerere (adresa, date, functie). { http.open("POST", adresa);
// stabilim tipul de continut trimis http.setRequestHeader("Content-Type",
"aplicatia/x-www-form-urlencoded;charset=UTF-8"); http.send(date);
// precizam functia de tratare a schimbarii de stare http.onreadystatechange = functie;
return false;
}
Mai ramane sa instantiem obiectul si sa expediem cererea :
var http = initializare( );
expediereCerere ("http://www.pinguin.info/serviciu/".
dateFormular, procesareRaspuns);
Drept exercitiu, cititorii pot incerca o abordare orientata-obiect a celor descrise mai sus.
Pe baza AJAX, un program JavaScript poate invoca asincron un serviciu Web (un exemplu bazat pe SOAP este furnizat in volumul Lenuta Alboaie, Sabin Buraga,
Servicii Web, aparut la Editura Polirom, Iasi, in 2006).