Scorrere i record di un file Xml con Javascript

Corso XML
Creazione di strutture XML, XSL ed altri linguaggi eXtensible

Scritto da Luca Ruggiero nella sezione Xml

Introduzione

L'oggetto recordset, di cui abbiamo già discusso nell'articolo Un motore di ricerca con JavaScript e XML, nella sua semplicità concettuale, è dotato di squisite funzionalità. Creato su misura per Javascript, in funzione di Xml, recordset si comporta analogamente ai driver utilizzati dai database per leggere i singoli record di una tabella, sfruttando quindi caratteristiche di malleabilità e versatilità nella consultazione dei dati di un file Xml.

Andiamo per gradi. I programmatori Microsoft conoscono ed apprezzano l'oggetto OLE, che non un'orazione in spagnolo :-) ma si tratta di un controllo ActiveX capace di scorrere i record di un database in maniera impeccabile, muovendosi tra i singoli record e leggendoli da destra verso sinistra e da sinistra verso destra, o volendo, dal basso verso l'alto e viceversa.

Javascript dispone nativamente di particolari metodi per scorrere le variabili di una tabella di dati, ad esempio di un Array(), dal primo all'ultimo, ed in sequenza nell'ordine descritto in precedenza, uno ad uno; detti metodi sono:

VariabileRecordset.MoveFirst() // Si sposta al primo record
VariabileRecordset.MoveNext() // Si sposta al record successivo
VariabileRecordset.MovePrevious() // Si sposta al record precedente
VariabileRecordset.MoveLast() // Si sposta all'ultimo record
Lo scopo pratico di questo articolo è quello di riuscire a leggere uno ad uno, e con una metodologia mirata, i record di un file Xml. Allo scopo creeremo due documenti, un file Html, ad esempio recordset.html, dividendo i codici Html e Javascript in distinte fasi; un file Xml, ad esempio database.xml, in cui ci limiteremo a conservare alcuni dati.

Buona lettura!

Concettualizzazione dell'esempio

L'applicazione Xml di esempio che andiamo a sviluppare, altro non è che una vista di una serie di record elencati singolarmente; l'esempio è strutturato con soli due campi, ma è spiegato di seguito come, eventualmente, anzi sicuramente, implementare il nostro database Xml con un maggior numero di campi.
Avremo quindi una pagina in cui compare un singolo record, ed una serie di bottono di navigazione del tipo

< Primo | « Precedente | Successivo » | Ultimo >

che ci permetterà di muoverci tra i vari record contenuti nel nostro file Xml, di cui mostro il codice nel paragrafo che segue.

Il file database.xml

Creiamo il nostro database nel file Xml descritto in precedenza, una semplice e chiara struttura:
<?xml version="1.0"?>

<root>
   <record>
      <id>1</id>
      <nome>Pippo</nome>
   </record>
   <record>
      <id>2</id>
      <nome>Paperino</nome>
   </record>
   <record>
      <id>3</id>
      <nome>Pluto</nome>
   </record>
   <record>
      <id>4</id>
      <nome>Topolino</nome>
   </record>
   <record>
      <id>5</id>
      <nome>Luca... c'est moi!!!</nome>
   </record>
</root>
Abbiamo, come al solito definito la Root Xml, il contenitore dei campi ed i campi stessi; non è importante il nome che assegnamo alla root ed al contenitore, ma è fondamentale l'operazione di nomina dei campi, venendo richiamati all'interno del codice Html per essere poi manipolati con Javascript.

La struttura "ospite" Html

La struttura Html che ospiterà i dati si divide ideologicamente in tre parti: il richiamo del file esterno Xml, il box che conterrà il singolo record selezionato, e la barra di navigazione tra i record.
Propongo i tre codice separati e commentati:
<xml id="DSO_Scorri" src="database.xml"></xml>
L'identificativo DSO_Scorri viene utilizzato per istanziare l'oggetto recordset in ogni sua occorrenza, poi viene normalmente puntato il file database.xml.
<table width="500" align="center" border="1">
 <tr>
   <td width="100"><b>ID</b></td>
   <td width="400"><span datasrc="#DSO_Scorri" datafld="id"></span></td>
 </tr>
 <tr>
   <td width="100"><b>NOME</b></td>
   <td width="400"><span datasrc="#DSO_Scorri" datafld="nome"></span></td>
 </tr>
</table>
Ecco due attributi già incontrati nell'Articolo Binding dei dati col DSO di cui ribadisco le funzionalità:
datasrc (Data Source) - fa riferimento al richiamo del file Xml, di conseguenza all'Xml stesso
datafld (Data Field) - fa riferimento al nome dei campi del file Xml
I bottoni che utilizzeremo per la navigazione dei record fanno riferimento a quattro differenti funzioni, descritte nel capitolo successivo; i loro nomi non lasciano spazio a riflessioni sul loro impiego:
<div align="center">
   <input type="button" value="Primo" onClick="Primo()">
   <input type="button" value="Precedente" onClick="Precedente()">
   <input type="button" value="Successivo" onClick="Successivo()">
   <input type="button" value="Ultimo" onClick="Ultimo()">
</div>
Siamo in dirittura di arrivo... lo script!

Le quattro funzioni di cui sopra sono molto semplici e composte da poche righe di codice; in effetti avremmo potuto inserire i rispettivi codici direttamente all'interno degli eventi onClick sui singoli bottoni, ma per praticità e chiarezza didattica, ho preferito scindere questi passaggi.

Ecco il codice:
function Primo() {
    DSO_Scorri.recordset.MoveFirst();
}
function Precedente() {
    DSO_Scorri.recordset.MovePrevious();
        if (DSO_Scorri.recordset.BOF) {
            DSO_Scorri.recordset.MoveNext();
        }
}
function Successivo() {
    DSO_Scorri.recordset.MoveNext();
        if (DSO_Scorri.recordset.EOF) {
            DSO_Scorri.recordset.MovePrevious();
        }
}
function Ultimo() {
    DSO_Scorri.recordset.MoveLast();
}
Le funzioni Primo() e Ultimo() sono associate ai bottoni con relativa etichetta; si limitano ad utilizzare i metodi MoveFirst() e MoveLast() (descritti nel primo paragrafo) per giungere rispettivamente al primo record registrato ed all'ultimo.

A differenza delle prime due funzioni appena descritte, le funzioni Precedente() e Successivo() (per scorrere i record uno ad uno) necessitano di un controllo, effettuato grazie alle proprietà EOF (fine del file / ultimo record) e BOF (inizio del file / primo record).
Se si lasciasse che i metodi MoveNext() e MovePrevious(), in questo caso, lavorassero da soli, si otterrebbe un errore del genere:

(x) Il record corrente corrisponde all'inizio o alla fine del file oppure è stato eliminato.
che a prima vista non è molto esplicativo (d'altra parte è un errore commentato da Microsoft...), ma comunque non ci stà bene che si verifichi!!!

E' quindi necessario controllare (caso della funzione Precedente()) che se ci si trova alla fine del file, il record corrente visualizzato sarà il successivo, altrimenti sarà normalmente il precedente.

Il sorgente completo

Siamo arrivato al traguardo, a questo punto potete gustare il codice sorgente completo, in modo da poter sperimentare quanto appreso nel corso della lettura:
<html>
 <head>
  <title>Scorrere i record di un file Xml con Javascript</title>
  <style type="text/css">
   body { font-family: Verdana; }
   td { font-size: 12px; }
   input { width: 100px; }
  </style>
  <script language="javascript" type="text/javascript">
   <!--
    function Primo() {
        DSO_Scorri.recordset.MoveFirst();
    }
    function Precedente() {
        DSO_Scorri.recordset.MovePrevious();
            if (DSO_Scorri.recordset.BOF) {
                DSO_Scorri.recordset.MoveNext();
            }
    }
    function Successivo() {
        DSO_Scorri.recordset.MoveNext();
            if (DSO_Scorri.recordset.EOF) {
                DSO_Scorri.recordset.MovePrevious();
            }
    }
    function Ultimo() {
        DSO_Scorri.recordset.MoveLast();
    }
   //-->
  </script>
 </head>
<body>

<xml id="DSO_Scorri" src="database.xml"></xml>

<h4 align="center">Scorrere i record di un file Xml</h4>

<br><br>

<table width="500" align="center" border="1">
 <tr>
   <td width="100"><b>ID</b></td>
   <td width="400"><span datasrc="#DSO_Scorri" datafld="id"></span></td>
 </tr>
 <tr>
   <td width="100"><b>NOME</b></td>
   <td width="400"><span datasrc="#DSO_Scorri" datafld="nome"></span></td>
 </tr>
</table>

<br><br>

<div align="center">
   <input type="button" value="Primo" onClick="Primo()">
   <input type="button" value="Precedente" onClick="Precedente()">
   <input type="button" value="Successivo" onClick="Successivo()">
   <input type="button" value="Ultimo" onClick="Ultimo()">
</div>

</body>
</html>

I più cliccati della sezione Xml

:: Estrarre dati da un file Xml con Javascript (32.755)

:: Un motore di ricerca con Xml e Javascript (25.675)

:: Applicare un foglio di stile Xsl ad un file Xml (21.760)

:: Leggere un file Xml con l'oggetto XMLDOM (17.988)

:: Introduzione all'oggetto XMLHTTP (16.744)

:: Leggere un Feed RSS con PHP (14.247)

:: Leggere un file Xml con Php (12.728)

:: Un sistema di login in Javascript ed Xml (11.814)

:: Inserire dati in un file Xml con l'oggetto XMLDOM (10.805)

:: Applicare un foglio di stile Css ad un file Xml (10.529)

IN EVIDENZA
DOWNLOAD