Sei sulla pagina 1di 3

Javascript e XML

Il grande vantaggio introdotto dall'XML trovo consista nell'aver facilitato lo scambio di informazioni. Utilizzare questo
formato ha risolto quasi tutti i problemi riguardo lo scambio di dati tra sistemi strutturalmente diversi e che altrimenti
avrebbero avuto bisogno di complicate interfacce per comunicare. Non credo di sbagliare sostenendo che se AJAX è il
cemento del Web 2.0 sicuramente XML è il mattone di questo nuovo modo di utilizzare e progettare il web. Un
documento XML ovviamente, necessita di essere manipolato (spesso trasformato) affinchè le informazioni riportate al
suo interno possano essere fruite. In questo articolo vedremo quindi come un file XML possa essere letto con Javascript
, le differenze del DOM nella manipolazione tra HTML e XML e infine, come applicare un foglio XSLT ad un XML
usando sempre Javascript.

Leggere un file XML: un metodo alternativo a XMLHTTPRequest


È noto, e direi piuttosto scontato, che leggere un file XML in remoto con Javascript può essere possibile usando
XMLHTTPRequest. Non molti sanno però che all'oggetto su cui si fonda AJAX si affianca una valida alternativa che
permette anch'essa di leggere file XML (e solo file di questo tipo). Al solito il metodo viene invocato nei due browser
piu diffusi, Internet Explorer e Firefox, in maniera differente ma a fronte di alcuni svantaggi, si dimostra essere
maggiormente adatto alla manipolazione di documenti XML. Vediamo allora come inizializzare i nostri oggetti e
commentiamo insieme il codice che segue:

if (document.implementation && document.implementation.createDocument)


{
xmlDoc = document.implementation.createDocument("", "", null);
xmlDoc.onload = readXML();
}
else (window.ActiveXObject)
{
xmlDoc = new ActiveXObject("MSXML2.DOMDocument");
xmlDoc.onreadystatechange = function () {
if (xmlDoc.readyState == 4) readXML()
};
}
xmlDoc.load("fileXMLdacaricare");

Per Firefox, questo metodo alternativo si invoca usando document.implementation mentre per Explorer occorre creare
una instanza ActiveX dell'oggetto MSXML2.DOMDocument. I metodi sono entrambi asincroni per default (ma
possono essere resi sincroni ponendo la proprietà async a false):
xmlDoc.async = false
e mentre per document.implementation esiste una funzione onload che ci dice quando il documento XML è stato creato,
per MSXML occorre fare un controllo sulla proprietà readyState i cui valori possono variare da 1 a 4: quando
readyState è pari a 4 appunto, significa che il file XML è stato completamente caricato (un po come con
XMLHTTPRequest).
In particolare nella nostra funzione, controlliamo che il documento sia stato caricato e poi facciamo partire la funzione
readXML() che nel nostro esempio ci servirà per studiare i vari metodi messi a disposizione per manipolare i dati del
file XML.
Torniamo brevemente al metodo usato con Firefox: come si vede dal codice, la funzione
document.implementation.createDocument ha tre argomenti che nel nostro caso sono vuoti. In ordine essi sono:
namespace, il tag root del documento e null perché le funzioni associate a questo parametro non sono state ancora
implementate. Usandoli possiamo creare anche documenti XML vuoti che potremmo riempire con le API del DOM.
Analogamente, ma in modo più macchinoso, anche Internet Explorer mette a disposizione le funzioni per creare
documenti XML vuoti. A cosa può servire questo? Ad esempio a creare un output XML per una base di dati sui cui dati
potremo lavorare manipolando poi l'XML salvato in locale, senza gravare ulteriormente sul nostro server.
Ritorniamo a parlare delle differenze tra XMLHTTPRequest e il metodo alternativo che stiamo usando.
XMLHTTPRequest può essere usato per qualsiasi tipo di documento di testo (non solo XML quindi) mentre il metodo
alternativo funziona solamente con file XML. XMLHTTPRequest funziona solo con il protocollo HTTP e quindi
qualsiasi altro protocollo non è utilizzabile per accedere ai file. Come avete intuito, il metodo alternativo non è invece
legato a nessun protocollo in particolare e quindi può caricare anche file XML che si trovano sul file system del vostro
server (oppure su un server ftp). Infine, quando usiamo il metodo alternativo, con HTTP possono essere generate
solamente richieste di tipo GET e non di tipo POST.

1
Come lo leggo?
Una volta compreso che la lettura del file XML può essere effettuata in due modi, passiamo a vedere come con il DOM
sia possibile usare le informazioni contenute nel nostro file XML. La funzione che segue legge un qualsiasi file XML e
ne mostra il nome del tag e il suo contenuto:

function readXML(app)
{
var x = xmlDoc.getElementsByTagName('item');
var text = '';
for (i=0;i < x.length;i++)
{
for (j=0;j < x[i].childNodes.length;j++)
{
if (x[i].childNodes[j].nodeType != 1) continue;
//text += x[i].childNodes[j].nodeName + ": " + x[i].childNodes[j].firstChild.nodeValue + "";
text += x[i].childNodes[j].nodeName + ": " + x[i].childNodes[j].firstChild.nodeValue + "";
}
}
alert(text);
var app = document.getElementById('textAPP');
app.innerHTML = text;
}

Analizziamo brevemente il codice: accedere ad un nodo dell'XML si riduce a navigare i suoi rami fino a raggiungere
l'elemento desiderato. Nel nostro caso (ripeto, un RSS) vogliamo visualizzare tutti gli elementi figli di tutti gli elementi
item. Quindi instanziamo un array di elementi item (var x = xmlDoc.getElementsByTagName('item')) dopodiché
iteriamo su quest'array e per ogni figlio dell'elemento (x[i].ChildNodes[j]).
L'esempio mostra le due caratteristiche principali di childNodes: NodeName, che ci permette di ottenere il nome del tag
e firstChild.nodeValue, che invece restituisce il valore eventualmente contenuto tra i tag. Come avrete notato c'è una
riga che non è stata commentata: if(x[i].childNodes[j].nodeType != 1). In realtà si tratta di un hack per Firefox. Il
browser della Mozilla Foundation infatti, interpreta come firstChild il nodo tra item e description che, in questo caso
però, non ha nessuno value da mostrare. Ciò causa un errore che blocca l'esecuzione dello script. È buona norma quindi
(una volta individuato il nodo padre) inserire questo piccolo hack.

HTML e XML: le differenze nel DOM (e non solo...)


Abbiamo appena visto che per accedere i valori di un file XML usiamo un approccio che ricorda molto da vicino il
DOM ben noto per le varie applicazioni Javascript tipiche del Web 2.0 (e non solo).
In effetti quando il W3C progettò le API per DOM, l'idea era quella di renderle valide per ogni linguaggio compreso
chiaramente XML: anzi, diciamo pure che XML ha inspirato la progettazione delle API tant'è che HTML viene gestito
dal DOM grazie ad una estensione delle API originali. Ma qual è la differenza fondamentale tra il DOM usato per
l'XML e quello usato per HTML? Facile: l'utilizzo della funzione getElementById. Infatti mentre in HTML questo è il
metodo per accedere ad un elemento della pagina (ovviamente se identificato da un id univoco) in XML è probabile che
il valore restituito usando questa funzione, sarà null. Questo perché in XML non è sufficiente dichiarare un attributo id
in un tag e accedere poi a quel tag con getElementById: occorre anche "tipizzare" l'attributo, e per farlo va definito il
DTD per il documento XML e poi dichiararlo nel DOCTYPE.
Un'altra differenza tra HTML e XML è che HTML ha una proprietà body che si riferisce al tag <body> mentre per
XML solo la proprietà documentElement si riferisce al tag root del documento. Infine, per accedere al valore di un
attributo di un tag in XML va utilizzato getAttribute(nomeAttributo) mentre per modificarlo si usa
setAttribute(nomeAttributo). Quindi: se abbiamo il tag: <esempioTag attr="ciao"> e vogliamo accedere al valore
dell'attributo attr, si scrive: getAttribute(attr). Ovviamente questa operazione non è permessa con documenti HTML.

2
Javascript, XML e XSLT
La naturale estensione di XML per la trasformazione di un documento XML in formati fruibili all'utente finale è
senz'altro XSL. In Javascript è possibile applicare un file XSL ad un file XML sia in Internet Explorer che in Firefox,
con la solita discrepenza sui metodi di base e sulle modalità di inizializzazione. Occorre però precisare in questo caso,
che il W3C non ha ancora definito nessuna API standard per le trasformazioni XSL con il DOM o con XML per
Javascript e quindi per una volta, giustifichiamo scelte diverse a fronte di una poco matura situazione ad "alti livelli".
Passiamo al concreto e partiamo con Firefox le cui API proprietarie per la trasformazione di documenti XML con XSL
viene garantita dall'oggetto XSLTProcessor. In Internet Explorer invece l'oggetto predisposto è TransformNode().
Vediamo nel seguente esempio come creare una funzione cross browser per applicare un file XSL (che supponiamo di
avere in remoto, cioè un URL) ad uno specifico nodo del nostro file XML (supponiamo di aver già riconosciuto quale
browser stiamo utilizzando e riusiamo la funzione per caricare file XML che abbiamo visto in precedenza, ovvero
l'oggetto ottenuto, XMLDoc che chiamiamo XSLDoc quando carichiamo il file XSL):

XSLDoc.load(URLdelFileXSL);
if (typeof XSLTProcessor != "undefined") {
//stiamo usando Firefox
var xsltProcessor = new XSLTProcessor();
xsltProcessor.importStylesheet(XSLDoc);
var app = xsltProcessor.transformToFragment(nodoDelDOMDaTrasformare);
} else {
//stiamo usando Internet Explorer
//quindi il nodo che vogliamo trasformare ha la funzione transformNode tra i suoi metodi
var app = nodoDelDOMDaTrasformare.TransformNode(XSLDoc)
}

In Firefox è possibile usare anche un altro metodo al posto di transformToFragment (che come TransformNode per IE,
restituisce un nodo) ed è transformToDocument: l'oggetto che se ne ricava è un document HTML se l'XSL produce
come output un HTML oppure un documento XML se l'XSL produce un file XML.

Javascript e XPath
Chiudiamo con un accenno alle espressioni XPath e le relative API del W3C per la selezione dei nodi nel DOM usando
questo approccio. Al solito anche qui, Firefox ha implementato le API usando il metodo evaluate() del document object,
che compila una espressione XPath in modo che sia possibile valutarla diverse volte in modo efficiente. Internet
Explorer invece, fornisce i due metodi selectSingleNode() e selectNodes() esclusivamente per documenti XML (e
quindi non funzionano con documenti HTML!). XPath è ovviamente una parte che richiederebbe una serie di articoli
per essere analizzata a fondo e per questo mi fermo qui, limitandomi all'introduzione degli strumenti che dovete usare
se volete cercare nodi all'interno dei vostri documenti, usando appunto Javascript.

Considerazioni Finali
Abbiamo visto quindi come Javascript si sia ormai evoluto, in un linguaggio che permette sofisticate operazioni un
tempo appannaggio esclusivamente dei linguaggi server side. Come già detto, molte di queste innovazioni hanno fatto si
che nascesse il Web come lo conosciamo oggi, e ovviamente XML è una parte fondamentale per l'evoluzione (anche)
futura della user experience durante la navigazione e la fruizione dei contenuto sul web. Javascript copre
completamente ogni aspetto necessario a maneggiare le informazioni in questo formato e in questo articolo ho cercato
di toccare un po' tutti gli aspetti. Come avrete notato inoltre, i browser che ho citato sono stati solamente Internet
Explorer e Firefox: questo perché il resto dei browser non ha ancora un supporto Javascript ad XSLT né tanto meno ad
XPath: in questi casi viene consigliato l'utilizzo di AJAXSLT una libreria sviluppata da Google. Questo è tutto. Alla
prossima e buon divertimento!

Potrebbero piacerti anche