Pagine

mercoledì 25 marzo 2015

XML DOM (1)

L'acronimo DOM sta per Document Object Model. L'XML DOM definisce uno standard per manipolare documenti xml. Oltre all'XML DOM è importante la conoscenza dell'HTML DOM. Quest'ultimo definisce gli oggetti e le proprietà di tutti i tags html, nonché i metodi per manipolarli. In questo post ci occuperemo dell'XML DOM.

Per il DOM ogni cosa in un documento xml è un nodo. Per il DOM:
  • L'intero documento xml è un "document node"
  • Ogni elemento xml è un "element node"
  • Il testo contenuto negli elementi xml è composto di "text nodes"
  • Ogni attributo è un "attribute node"
  • I commenti sono "comment nodes"

Nel seguito useremo come file xml di esempio il file books.xml.

<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
  <book category="cooking">
    <title lang="en">Everyday Italian</title>
    <author>Giada De Laurentiis</author>
    <year>2005</year>
    <price>30.00</price>
  </book>
  <book category="children">
    <title lang="en">Harry Potter</title>
    <author>J K. Rowling</author>
    <year>2005</year>
    <price>29.99</price>
  </book>
  <book category="web">
    <title lang="en">XQuery Kick Start</title>
    <author>James McGovern</author>
    <author>Per Bothner</author>
    <author>Kurt Cagle</author>
    <author>James Linn</author>
    <author>Vaidyanathan Nagarajan</author>
    <year>2003</year>
    <price>49.99</price>
  </book>
  <book category="web" cover="paperback">
    <title lang="en">Learning XML</title>
    <author>Erik T. Ray</author>
    <year>2003</year>
    <price>39.95</price>
  </book>
</bookstore>


Il Parser


Tutti i moderni browser hanno un built-in parser, capace di manipolare documenti xml. Il parser converte un documento xml in un oggetto XML DOM al quale si può accedere usando il linguaggio javascript. Inoltre l'oggetto XML DOM contiene metodi per attraversare un albero xml, accedere ai nodi, inserire nodi, eliminare nodi. Prima di ciò è tuttavia necessario caricare in memoria il documento xml. Questo può essere fatto usando una funzione javascript standard, che nei nostri esempi chiameremo loadXMLDoc(filename). Eccola:

function loadXmlDoc(filename)
{
if (window.XMLHttpRequest)
  {
  xhttp=new XMLHttpRequest();
  }
else // code for IE5 and IE6  {
  xhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
xhttp.open("GET",filename,false);
xhttp.send();
return xhttp.responseXML;
}

Conviene memorizzare questa funzione in un file esterno (che chiameremo "xmlFunctions.js"), al quale si farà riferimento inserendo un'apposita direttiva nella sezione <head> della pagina web (evidenziata in giallo).


<!DOCTYPE html>

<html>

<head>

<script src="xmlFunctions.js"></script>

</head>

<body>


</body>
</html>

A questo punto siamo pronti per il nostro primo esperimento: vogliamo caricare, leggere e scrivere in una pagina web tutti i titoli del file books.xml.

Scriviamo dunque una semplice pagina html con il seguente codice:

<!DOCTYPE html>
<html>

<head>
<script src="xmlFunctions.js"></script>
</head>
<body>
<div id="pippo"/>
<script type="text/javascript" language="javascript">
xmlDoc=loadXmlDoc("books.xml");
var htmTxt="";
x=xmlDoc.getElementsByTagName("title");
for (i=0;i<x.length;i++)
 { 
 htmTxt+=x[i].childNodes[0].nodeValue + "<br/>";
 }
document.getElementById("pippo").innerHTML=htmTxt;
</script>
</body>
</html>

Salviamo la pagina html con il nome "leggiNodi.html" e apriamola. Vengono visualizzati i titoli dei quattro libri descritti nel file books.xml.

Anche il codice javascript scritto nella pagina html può essere messo in un file apposito, che verrà referenziato nella sezione <head>. In tal modo il codice html della pagina web sarà più leggibile, oltre ad aprirsi alla possibilità che persone diverse lavorino alla realizzazione della stessa funzionalità. Chiamiamo il file esterno "pageCode.js". Operando in tal modo la nostra procedura sarà composta da tre files:
  1. il file xmlFunctions.js contenente il codice javascript, cioè la funzione loadXmlDoc(fileName), necessario per caricare il file books.xml. Questa funzione può essere usata per aprire un generico altro file xml semplicemente passandogli il nome.
  2. il file pageCode.js contenente il codice javascript necessario per navigare nell'oggetto xmlDocument restituito dalla chiamata alla funzione loadXmlDoc(filename). Per rendere questo codice riutilizzabile la funzione che esso contiene accetterà tre parametri: il nome del file xml da caricare, il nome del nodo da ricercare, il nome del tag html nel quale iniettare il risultato.
  3. La pagina html vera e propria, con il contenitore identificato dal tag <div> con identificativo "pippo".
Dopo queste modifiche il codice contenuto nel file xmlFunctions.js resta invariato, mentre cambia il codice contenuto nel file pageCode.js:

function fillDiv(xmlFile, nodeName, tagId)
{
try{
xmlDoc=loadXMLDoc(xmlFile);
}
catch (err){alert(err.message);}
var htmTxt="";

var x=xmlDoc.getElementsByTagName(nodeName);

 for (i=0;i<x.length;i++)
   {
   htmTxt+=x[i].childNodes[0].nodeValue + "<br/>";
   }
 document.getElementById(tagId).innerHTML=htmTxt;
}


Si noti, nel codice precedente, il blocco try-catch (evidenziato in giallo) del quale parleremo in altra occasione. Esso serve per intercettare eventuali errori e far comparire un messaggio che lo descrive.

A questo punto il codice della pagina html si riduce notevolmente:

<!DOCTYPE html>
<html>
<head>
<script src="xmlFunctions.js"></script>
<script src="pagecode.js"></script>
</head>
<body>
<div id="pippo"/>
<script type="text/javascript" language="javascript">fillDiv('books.xml','title','pippo');</script>
</body>
</html>

Considerazioni


Abbiamo separato tutta la procedura in tre blocchi per renderla più gestibile e consentire, eventualmente, a più persone di lavorare su di essa. 

Nel file xmlFunctions.js si mettono le funzioni di uso generale, cioè riusabili in molti altri casi. Queste sono in genere scritte da specialisti javascript che le rendono disponibili a moltissimi programmatori.

Nel file pageCode.js si mettono le funzioni usate dalla specifica pagina html su cui stiamo lavorando. Il suo codice può essere scritto dalla stessa persona che scrive anche la pagina html, come pure da un'altra persona.

Il file html vero e proprio deve contenere solo i riferimenti ai due precedenti files javascript, oltre naturalmente alla chiamata della/delle funzioni in esse contenute, con gli eventuali parametri da passare. Nel nostro caso tali parametri sono, come già detto:
  1. il file xml nel quale si trovano i dati (nel nostro caso books.xml)
  2. il nodo del file xml il cui contenuto si vuole visualizzare (nel nostro caso "title")
  3. l'identificativo del tag <div> nel quale si vuole iniettare il risultato. Nel nostro caso esso è "pippo" e la sintassi è <div id="pippo"/>
Ovviamente, nella pagina html deve essere presente il tag <div id="pippo"/>.

In particolare, questa suddivisione del lavoro consente al programmatore della pagina html di minimizzare le sue responsabilità e il suo carico di lavoro per concentrarsi solo ed esclusivamente sugli aspetti grafici e testuali. A titolo di esempio ho preparato questa seconda pagina html nella quale è presente, oltre alle quattro righe della prima (quelle evidenziate in giallo), molti altri contenuti, dei quali chi scrive l'html è responsabile. Basta, per visualizzare i dati del file xml in questa nuova pagina html, che egli si ricordi di inserire anche le suddette quattro righe.

Nessun commento:

Posta un commento