Încărcarea XML folosind XMLHttpRequest
Formatul XML reprezintă un format popular de stocare și transmitere a datelor. Să examinăm cum să încărcăm un document XML pe o pagină web folosind o cerere ajax.
Ca server, la fel ca în articolul anterior, vom utiliza Node.js ca cea mai simplă opțiune, dar, desigur, dacă doriți, puteți utiliza orice altă tehnologie de nivel server sau un server web.
Astfel, să definim pentru proiect un folder pe discul dur, în care vom crea trei fișiere:
- index.html: pagina principală a aplicației
- users.xml: fișierul XML cu date
- app.js: fișierul aplicației server, care va utiliza Node.js
Definirea datelor
Fișierul users.xml va reprezenta datele încărcate și să aibă următorul conținut:
<?xml version="1.0" encoding="UTF-8" ?>
<users>
<user name="Tom" age="39">
<contacts>
<email>tom@smail.com</email>
<phone>+1234567890</phone>
</contacts>
</user>
<user name="Bob" age="43">
<contacts>
<email>bob@tmail.com</email>
<phone>+1334567181</phone>
</contacts>
</user>
<user name="Sam" age="28">
<contacts>
<email>sam@xmail.com</email>
<phone>+1434567782</phone>
</contacts>
</user>
</users>
Aici elementul users reprezintă un set de utilizatori, fiecare dintre aceștia fiind reprezentat de elementul user. Pentru fiecare astfel de element sunt definite două atribute: name (numele utilizatorului) și age (vârsta utilizatorului). Și, de asemenea, elementul user are un element încorporat contacts, care reprezintă datele de contact ale utilizatorului sub forma elementelor încorporate phone și email.
Definirea serverului
Fișierul app.js va reprezenta codul serverului Node.js. Să definim în acesta următorul cod:
const http = require("http");
const fs = require("fs");
http.createServer((request, response)=>{
// dacă sunt solicitate datele xml
if(request.url == "/data"){
fs.readFile("users.xml", (_, data) => response.end(data));
}
else{
fs.readFile("index.html", (_, data) => response.end(data));
}
}).listen(3000, ()=>console.log("Serverul a fost lansat la adresa http://localhost:3000"));
Să trecem rapid prin cod. La început, se conectează pachetele cu funcționalitatea pe care intenționăm să o utilizăm:
const http = require("http"); // pentru prelucrarea cererilor de intrare
const fs = require("fs"); // pentru citirea fișierelor de pe discul dur
Pentru crearea serverului se folosește funcția http.createServer(). În această funcție se transmite o funcție-handler, care este apelată de fiecare dată când la server sosește o solicitare. Această funcție are doi parametri: request (conține datele solicitării) și response (gestionează trimiterea răspunsului).
În funcția-handler, folosind proprietatea request.url putem obține calea resursei către care a fost trimisă solicitarea. Astfel, în acest caz, dacă a venit o solicitare pe calea "/data", atunci trimitem users.xml:
if(request.url == "/data"){
fs.readFile("users.xml", (_, data) => response.end(data));
}
Pentru citirea fișierului se utilizează funcția fs.readFile. Primul parametru al funcției - adresa fișierului (în acest caz se presupune că fișierul se află în același folder cu fișierul serverului server.js). Al doilea parametru - o funcție care este apelată după citirea fișierului și primește conținutul său prin al doilea său parametru data.
Pentru toate celelalte solicitări se trimite în răspuns fișierul index.html:
else{
fs.readFile("index.html", (_, data) => response.end(data));
}
La sfârșit, cu ajutorul funcției listen() lansăm serverul web pe portul 3000. Adică serverul va fi lansat la adresa http://localhost:3000/
Încărcarea XML pe pagina web
Pentru a obține fișierul "users.xml" de pe server, să definim în fișierul index.html următorul cod:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>FDC.COM</title>
</head>
<body>
<script>
const xhr = new XMLHttpRequest();
xhr.onload = () => {
if (xhr.status == 200) {
const xml = xhr.responseXML;
console.log(xml);
}
};
xhr.open("GET", "/data"); // cerere GET către /data
xhr.responseType = "document"; // stabilim tipul de răspuns
xhr.setRequestHeader("Accept", "text/xml"); // acceptăm doar xml
xhr.send(); // executăm solicitarea
</script>
</body>
</html>
Pentru a obține datele se trimite o solicitare la adresa "/data". Pentru ca datele obținute să fie automat interpretate ca un document XML, proprietății responseType i se atribuie valoarea "document".
xhr.responseType = "document";
În plus, ar trebui să setăm pentru antetul Accept valoarea "text/xml" sau "application/xml", pentru a accepta date doar în format XML:
xhr.setRequestHeader("Accept", "text/xml");
În handlerul evenimentului onload, documentul XML este disponibil prin proprietatea responseXML sub forma unui obiect de tip Document, care în acest caz este pur și simplu afișat în consolă:
xhr.onload = () => {
if (xhr.status == 200) {
const xml = xhr.responseXML;
console.log(xml);
}
};
După definirea tuturor fișierelor, în consolă ne vom deplasa la folderul serverului folosind comanda cd și vom lansa serverul folosind comanda node app.js

După lansarea serverului, putem accesa în browser adresa http://localhost:3000, unde ne va fi afișată pagina, în codul JavaScript al căreia va avea loc o solicitare la adresa "/data". Serverul va trimite în răspuns conținutul fișierului users.xml, iar consola browserului va afișa acest conținut:

Afișarea datelor din documentul XML pe pagina
Acum să complicăm sarcina - presupunem că trebuie să afișăm datele despre utilizatori din XML într-un tabel pe pagina web. Pentru aceasta, să modificăm codul index.html în modul următor:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>FDC.COM</title>
</head>
<body>
<div id="content"></div>
<script>
const contentDiv = document.getElementById("content");
const xhr = new XMLHttpRequest();
xhr.onload = () => {
if (xhr.status == 200) {
const xmlDoc = xhr.responseXML;
const table = createTable();
// selectăm toate elementele user
const users = xmlDoc.getElementsByTagName("user");
for (let i = 0; i < users.length; i++) {
const user = users[i];
const userName = user.getAttribute("name");
const userAge = user.getAttribute("age");
const contact = user.querySelector("contacts email").textContent;
const row = createRow(userName,
userAge, contact);
table.appendChild(row);
}
contentDiv.appendChild(table);
}
};
xhr.open("GET", "/data");
xhr.responseType = "document";
xhr.setRequestHeader("Accept", "text/xml");
xhr.send();
// creăm un tabel
function createTable() {
const table = document.createElement("table");
const headerRow = document.createElement("tr");
const nameColumnHeader = document.createElement("th");
const ageColumnHeader = document.createElement("th");
const contactColumnHeader = document.createElement("th");
nameColumnHeader.appendChild(document.createTextNode("Nume"));
ageColumnHeader.appendChild(document.createTextNode("Vârstă"));
contactColumnHeader.appendChild(document.createTextNode("Contacte"));
headerRow.appendChild(nameColumnHeader);
headerRow.appendChild(ageColumnHeader);
headerRow.appendChild(contactColumnHeader);
table.appendChild(headerRow);
return table;
}
// creăm o singură linie pentru tabel
function createRow(userName, userAge, userContact) {
const row = document.createElement("tr");
const nameColumn = document.createElement("td");
const ageColumn = document.createElement("td");
const contactColumn = document.createElement("td");
nameColumn.appendChild(document.createTextNode(userName));
ageColumn.appendChild(document.createTextNode(userAge));
contactColumn.appendChild(document.createTextNode(userContact));
row.appendChild(nameColumn);
row.appendChild(ageColumn);
row.appendChild(contactColumn);
return row;
}
</script>
</body>
</html>
În acest caz, încărcăm tabelul pe pagină în elementul cu id="content", pe care îl obținem în codul JavaScript în elementul contentDiv.
const contentDiv = document.getElementById("content");
Pentru crearea tabelului sunt definite două funcții auxiliare. Funcția createTable creează un element table cu un singur rând - antetele coloanelor. Funcția createRow primește prin parametri numele, vârsta și contactele utilizatorului și pentru acestea creează un rând.
În partea principală a codului, efectuăm o solicitare către server. Deoarece răspunsul serverului va reprezenta un document XML de tip Document, putem utiliza metode standard precum getElementsByTagName sau querySelector pentru a găsi elementele necesare în document. La început, selectăm toate elementele user:
const xmlDoc = xhr.responseXML;
const table = createTable();
// selectăm toate elementele user
const users = xmlDoc.getElementsByTagName("user");
Apoi, parcurgem toate elementele user și selectăm pentru fiecare atributele name și age, precum și elementul încorporat email:
for (let i = 0; i < users.length; i++) {
const user = users[i];
const userName = user.getAttribute("name");
const userAge = user.getAttribute("age");
const contact = user.querySelector("contacts email").textContent;
const row = createRow(userName, userAge, contact);
table.appendChild(row);
}
Pentru fiecare element user se creează un rând, care apoi este adăugat în tabel.
Astfel, la accesarea paginii index.html va fi încărcat documentul XML, pe baza căruia va fi creat un tabel.
