Un motore di ricerca con Xml e Javascript

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

Scritto da Luca Ruggiero nella sezione Xml

Comparso su HTML.it il 6 Settembre 2002 - E' vietata la riproduzione, anche parziale, senza esplicito consenso dell'autore

Introduzione

Una delle caratteristiche che rendono "usabile", ovvero navigabile agevolmente, un sito Web è la presenza di un motore di ricerca interno per parole chiave che consente all'utente di giungere, con una certa immediatezza, alla pagina, o alle pagine, in cui sono riportati gli argomenti che suscitano il suo interesse.

Per ottenere un prodotto del genere ci sono diverse strade, la più utilizzata in assoluto è senza alcun dubbio quella di installare un database sul server ed interrogarlo con un programmino scritto mediante l'utilizzo di un linguaggio di scripting server-side, come Asp, Php, Jsp, Cgi o che dir si voglia.

Non tutti gli sviluppatori, chi per un motivo chi per un altro, hanno la possibilità o sono in grado di sviluppare un'applicazione Web del genere, magari per inesperienza o perchè non dispongono di un server Web che offraqueste caratteristiche.

Per ovviare a questa situazione è possibile utilizzare un linguaggio di scripting client-side come Javascipt, memorizzando parole chiave, url, titolo e descrizione in degli Array() ciclandoli e stampando a video i risultati di una specifica ricerca.

Altra soluzione è quella di ricorrere ad Xml ed all'oggetto recordset per ovviare all'utilizzo di script troppo complessi e più difficilmente gestibili in termini di ampliamento del "database" generato da semplici Array().

Bene, in questo articolo ci muoveremo verso quest'ultima direzione.

Pro e contro dell'utilizzo di un file Xml invece che di un database

Utilizzare un database ed un programmino server-side per interrogare il databae vuol dire usufruire di una maggior versatilità nei criteri di interrogazione del database, grazie all'utilizzo di Sql che, nella sua semplicità e potenza, permette in maniera impeccabile di effettuare query (interrogazioni) di una certa complessità, e di ottenere in output un numero ed un tipo di record che rispecchia il più fedelmente possibile i parametri di ricerca impostati dall'utente (le parole chiave per la ricerca).

Questo però comporta anche un lavoro, in termini di manutenzione e sicurezza dei dati, maggiore rispetto ad un'applicazione client-side, nonchè un tempo di attesa superiore, dato che il dialogo deve avvenire ad ogni richiesta tra client e server Web, mentre con un'applicazione client-side il tutto si svolge in locale sul computer client dell'utente finale.

Personalmente considero comunque ottimale questa soluzione, dato che le nuove tecnologie per le connessioni ad Internet (ISDN, ADSL, HDSL, ecc...) hanno notevolmente diminuito i tempi di attesa dell'utente.

Fatto stà che in questo contesto ci muoveremo diversamente: utilizare Xml (piuttosto che un semplice Javascript) permette, ad esempio, di interfacciarsi con un database convertendo i veri e propri recordset in un file Xml, quindi è possibile procedere nell'analoga maniera aggiungendo al lavoro finale, che sarà il culmine di questo articolo, un programmino che attuerà detta conversione, ma non è questa la sede giusta per discutere di ciò.

Analisi e concettualizzazione del problema

Per creare un'applicazione client-side col supporto di Xml, come quella descritta in precedenza, non è tuttavia possibile pensare che non occorra utilizzare un programmino che si interfacci col file Xml, utilizzeremo un semplice script Javascript: le specifiche di Xml e del DOM (Document Object Model) dettate dal W3C descrivono il Javascript come il linguaggio più adatto a lavorare con l'Xml.

Abbiamo bisogno sostanzialmente di due file, un file Xml che contiene i dati che ci interessano in una struttura organizzata ad hoc, ed un file Html che contiene il modulo di ricerca, organizzato anche per ricevere in output i risultati, ed il Javascript la cui funzione abbiamo descritto in precedenza; per comodità e chiarezza includeremo comunque nel file Html un file Javascript esterno con estensione .js.

Andiamo per gradi analizzando i tre file uno ad uno.

Costruzione del "database" Xml

Il file Xml che fungerà da database ha una struttura molto semplice e chiara, root, sub-directory e nomi dei "campi", classica struttura di base di questa tipologia di file.

Dobbiamo organizzarci in questo modo, creiamo tre campi: titolo, che verrà stampato a video e sarà il testo linkabile e fungerà anche da parola chiave, url che conterrà gli indirizzi Web associati all'intero record e descrizione il cui nome è abbastanza esplicativo, una semplice descrizione del link che si andrà a visitare.

Costruiamo il file database.xml:

<?xml version="1.0"?>

<root>
   <ricerca>
      <titolo>Pippo</titolo>
      <descrizione>Sezione dedicata a Pippo</descrizione>
      <url>pippo.html</url>
   </ricerca>
   <ricerca>
      <titolo>Pluto</titolo>
      <descrizione>Sezione dedicata a Pluto</descrizione>
      <url>pluto.html</url>
   </ricerca>
   <ricerca>
      <titolo>Paperino</titolo>
      <descrizione>Sezione dedicata a Paperino</descrizione>
      <url>paperino.html</url>
   </ricerca>
</root>
In seguito, in fase di realizzazione dello script Javascript, ci tornerà utile come predetto l'oggetto recordset di Xml che si interfaccia ad con un file Xml sfruttando i nomi dei campi (in questo caso quindi titolo, url e descrizione), nè più nè meno come lavora l'oggetto ADO (ActiveX data Object) di Microsoft.

Attenzione, non sto uscendo fuori tema! ADO è un controllo in grado di stabilire una connessione con un database sulla scorta di un motore (driver) chiamato ODBC (Open Database Connectivity): ADO lavora in Xml!!!

E' quindi ovvio pensare che l'oggetto recordset di Xml, sulla scorta delle informazioni appena date, sia perfettamente in grado di lavorare in locale seguendo gli standard dettati dal W3C per Javascript.

Costruzione del modulo di ricerca Html e della struttura di output

Il file Html che andremo a presentare è minimamente formattato per essere eventualmente già bello e pronto per l'uso, è di una semplicità che sfiora i livelli del quasi grado di minima esperienza in Html :-) lo chiameremo ricerca.htm, vediamo il codice:
<html>
 <head>
  <title>lukeonweb.net</title>
  <basefont size="2" face="Verdana">
  <script language="javascript" src="elabora.js"></script>
 </head>
<body onLoad="document.modulo.cerca.focus()">

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

<div>
 <form name="modulo">
  Cerca nel sito
  <input type="text" name="cerca">
  <input type="button" value="Cerca" onClick="Ricerca()">
 </form>
</div>

<div id="risultati"></div>

</body>
</html>
Il file è, nello svolgimento della sua funzione, divisibile in tre punti essenziali:

1. includiamo il file Javascript esterno (che creeremo tra breve) con la stringa
<script language="javascript" src="elabora.js"></script>
2. ci "connettiamo" al file database.xml con la stringa
<xml id="id_database" src="database.xml"></xml>
oltre a stabilire un source per localizzare il file Xml (che in questo caso si trova nella stessa posizione) gli assegniamo un identificativo di tipo id che ci servirà in seguito nello script Javascript per collaborare con l'oggetto recordset ed identificare in maniera univoca l'Xml di cui sopra

3. creiamo un layer di testo vuoto per visualizzare in output sulla pagina i record trovati all'interno del file Xml, assegnando anche a questo un'altro identificativo di tipo id
<div id="risultati"></div>
Elaborazione Javascript del "database" Xml

Siamo sul rettilineo finale!

Creiamo adesso il file elabora.js ed inseriamo in maniera dogmatica il seguente codice, comunque opportunamente commentato:
function Ricerca() {

   //Localizziamo la casella di testo del modulo Html di ricerca
   //ed eseguiamo un controllo case-insensitive col metodo toUpperCase()
   var stringa = document.modulo.cerca.value.toUpperCase();

      //Creiamo un controllo per cui se la ricerca viene eseguita per nessun carattere
      //verrà restituito all'utente un messaggio di avviso direttamente a video sulla pagina
      if ((stringa == "") || (stringa == "undefined")) {
         risultati.innerHTML = "Inserire un termine per eseguire una ricerca";
         return false;
      }

      //Ci posizioniamo ora sul primo record trovato sul file Xml
      id_database.recordset.moveFirst();

      //In questa variabile (inizialmente vuota) costruiremo dinamicamente
      //il testo opportunamente formattato dell'output della ricerca
      var estrai = "";

      //Eseguiamo un ciclo while() che sfoglia i record del file Xml fino all'ultimo
         while (!id_database.recordset.EOF) {
            var titolo = id_database.recordset("titolo").value.toUpperCase();
               if (titolo.indexOf(stringa) >= 0) {
                  estrai += "<div><a href=" + id_database.recordset("url") + ">"
                         + id_database.recordset("titolo")
                         + "</a><br>" + id_database.recordset("descrizione")
                         + "</div><br>";
               }
               //e ci riposizioniamo all'inizio del file
               id_database.recordset.moveNext();
         }

         //Verifichiamo che ci siano record disponibili per la ricerca
         //se non ce ne sono restituiamo all'utente un messaggio di avviso
         if ((estrai == "") || (estrai == "undefined")) {
            risultati.innerHTML = "Nessun risultato per la ricerca";
            return false;
         }
         //oppure i record trovati
         else {
            risultati.innerHTML = estrai;
         }
}
Credo che i commenti non lascino spazio a molti dubbi sul funzionamento di questo script, l'unica parte che vorrei riprendere ed analizzare un pochino più approfonditamente riguarda il ciclo while() sull'oggetto recordset, ripropongo il codice:
while (!id_database.recordset.EOF) {
   var titolo = id_database.recordset("titolo").value.toUpperCase();
      if (titolo.indexOf(stringa) >= 0) {
         estrai += "<div><a href=" + id_database.recordset("url") + ">"
                + id_database.recordset("titolo")
                + "</a><br>" + id_database.recordset("descrizione")
                + "</div><br>";
      }
      id_database.recordset.moveNext();
}
Il ciclo si perpetua fino a quando il recordset non è diverso (cioè fino a quando non raggiunge) la fine del file Xml, dopo averlo sfogliato tutto, per questo utilizziamo la proprietà EOF (End Of File), dobbiamo adesso identificare il titolo del record che estrarremo dal file Xml (che funge anche da parola chiave per la ricerca), utilizzando la sintassi id_database.recordset("titolo"), ovvero "il recordset (associato al campo titolo)", per eseguire la ricerca utilizziamo il metodo indexOf() passandogli la variabile stringa associata alla casella di testo del modulo di ricerca, se trova una rispondenza allora il settaggio avviene su true, altrimenti su false (ovvero stabiliamo se restituire o meno risultati).

Il metodo moveNext() associato all'oggetto recordset in questione, termina il ciclo e ci riposiziona virtualmente al primo record del file Xml.

Conclusioni

Ci siamo limitati a sviluppare solo una serie di ragionamenti, al dilà del fatto che abbiamo utilizzato una determinata tecnologia implementata con una data sintassi, gli stessi ragionamenti possono essere semplicemente convertibili ed essere utilizzati per sviluppare applicazioni analoghe, simili, o anche diverse, col linguaggio e con gli strumenti che più ci convengono.

Che sia un bene o che sia un male ricordiamoci sempre che una tale tecnologia difficilmente garantisce il funzionamento con browser, ma soprattutto server Web che non siano di casa Microsoft.

I più cliccati della sezione Xml

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

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

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

:: Introduzione all'oggetto XMLHTTP (16.951)

:: Leggere un Feed RSS con PHP (14.623)

:: Scorrere i record di un file Xml con Javascript (14.517)

:: Leggere un file Xml con Php (12.862)

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

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

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

IN EVIDENZA
DOWNLOAD