INDICE: Introduzione Tesina XML Pag. 3 Introduzione Caratteristiche Sintassi Parser Dichiarazioni Document Type Definition (DTD) XML Schema Definition (XSD) Pag. 6 XPath Pag. 12 XQuery Costrutto FLWOR Interrogazione orario scolastico Pag. 13 XML StyleSheet Language (XSL) XSLT XSL-FO Pag. 18 Java e XML JDOM Pag. 22 Trasformazione database Pag. 27 Editor XML Pag. 30 Servlet Tecnologia Servlet Query su XML con XSL e Servlet Pag. 35 Riferimenti Bibliografia Sitografia Pag. 46 XML e Tecnologia Servlet 2 INTRODUZIONE L'obiettivo di questa tesina era inizialmente la consultazione del database dell'orario scolastico in formato XML. La maggior parte del tempo è stata assorbita dallo studio di XML e tutto ciò che lo riguarda. Dopo numerosi tentativi, abbiamo realizzato una servlet (un’applicazione Java-web lato server), che con l’aiuto di XSL e altri aspetti trattati nella tesina è in grado di svolgere il compito prefissato. Ma questa è solo una piccola parte della tesina, che cerca soprattutto di dare uno sguardo generale al mondo XML, un mondo decisamente ampio ed in continua evoluzione. Ognuno dei numerosi argomenti trattati, è supportato da esempi per rendere la spiegazione più chiara al lettore. INTRODUZIONE XML XML (eXtensible Markup Language) non è un vero e proprio linguaggio, è un metalinguaggio che permette di creare dei linguaggi personalizzati di markup. E’ sviluppato dal World Wide Web Consortium (W3C), un ente composto da 350 ricercatori sparsi in tutto il globo che guidano lo sviluppo del WWW e dei suoi standard. Sebbene sia stato approvato solo nel 1998, questo progetto parte da molto lontano. XML deriva, come HTML da GML (Generalized Markup Language), creato dall’IBM negli anni ’60 quale sistema di pubblicazione dei documenti interni che sfruttasse la standardizzazione della struttura dei documenti, semplificandone lo scambio e la modifica del contenuto. Nel 1986 venne creato SGML (Standard Generalized Markup Language), un estensione di GML estremamente potente ma molto complessa. Da esso derivano l’HTML, specializzato per la visualizzazione del testo in Internet e l’XML, creato per trattare i dati. CARATTERISTICHE DIFFERENZE TRA HTML E XML E’ importante stabilire che HTML e XML sono due cose differenti e non derivano l’uno dall’altro. Hanno obiettivi e strutture diverse: HTML XML Finalizzato alla visualizzazione dei dati Impossibile definire nuovi tag. Bisogna utilizzare quelli predefiniti. Un tag rappresenta il modo in cui un dato viene rappresentato. E’ impossibile rappresentare la struttura di un documento HTML. I dati contenuti all’interno non possono essere letti agevolmente da un software Finalizzato al trattamento dei dati Ognuno può creare i propri tag per definire nuovi elementi. Un tag rappresenta un dato. E’ possibile rappresentare e modificare la struttura di un documento XML. Un software può leggere facilmente i dati contenuti nel documento XML E’ comunque possibile rappresentare un documento XML in forma grafica, grazie ad XSL, un linguaggio definito tramite XML che vedremo in seguito. XML e Tecnologia Servlet 3 VANTAGGI E SVANTAGGI DELL’XML XML ha numerosi vantaggi: Flessibilità: l’XML è composto ‘solamente’ da dati racchiusi da tag. E’ possibile creare e modificare la struttura del documento XML. XML è il mezzo di comunicazione universale per i tutti sistemi informatici. XML abbatte le barriere dei sistemi proprietari e permette l'interoperabilità delle risorse che oggi è fondamentale nel web. Compatibilità: con l'XML possiamo rendere possibile la comunicazione tra applicazioni molto differenti tra di loro. XML amplifica la comunicazione. Portabilità: grazie proprio alla compatibilità dell'XML la nostra applicazione diventa molto più portabile in quanto si basa su un linguaggio che ha un livello di astrazione superiore rispetto agli altri. Costo: l’XML è free, ognuno può utilizzare XML e i suoi derivati nella propria applicazione senza pagare diritti. I suoi svantaggi sono: Complessità: l’XML è complesso da studiare e capire completamente. Può essere un ostacolo per la realizzazione di progetti basati su questa tecnologia. Lentezza: un documento XML, proprio per la sua natura testuale impiega più spazio in memoria e necessita di più tempo per una elaborazione da parte del software rispetto a basi di dati, o altri file binari. SINTASSI XML XML è un linguaggio di markup, di conseguenza si basa sui tag. In un documento XML è possibile definire i propri tag. A differenza dell’HTML, ogni tag aperto deve essere anche chiuso. L’XML è case-sensitive, per cui il tag ‘nome’ è diverso dal tag ‘NOME’. Se un tag è vuoto, ovvero non ha testo al proprio interno, può essere chiuso con questa sintassi: <nome/> Altrimenti si utilizza la solita sintassi: <nome> Gino </nome> Vediamo un esempio di documento XML: <?xml version="1.0"?> <libreria> <libro anno=”1969”> <titolo> Il giorno della civetta </titolo> <autore> Sciascia </autore> </libro> <libro anno=”1994”> <titolo> Sostiene Pereira </titolo> <autore> Tabucchi </autore> XML e Tecnologia Servlet 4 </libro> </libreria> Un elemento è un tag e ciò che il tag contiene. L’elemento libreria è l’elemento principale o root del documento. L’elemento libro è figlio dell’elemento libreria, e a sua volta è padre degli elementi titolo ed autore. Anno è un attributo dell’elemento libro. Il valore dell'attributo è compreso tra apicetti o virgolette, un attributo non può avere valore nullo e non possono essere presenti due attributi con lo stesso nome all'interno dello stesso elemento. I caratteri compresi tra un tag aperto e chiuso è il valore dell’elemento. Nel caso di libro, il suo valore comprende gli elementi titolo e autore, quindi anche i tag. La prima riga è un po' particolare. Ogni documento XML dovrebbe iniziare così, serve a definire lo standard che si usa; possono essere definiti anche altri aspetti sotto forma di attributi: standalone, se ha valore yes significa che il documento non fa riferimento ad altri file esterni. encoding, il nome della codifica dei caratteri, UTF-8 o UTF-16 per indicare la codifica Unicode a 8 o 16 bit. RIFERIMENTI: In XML è possibile fare riferimento a file esterni. Questi riferimenti sono generalmente verso due tipi di file: Dichiarazioni della struttura del documento (generalmente file DTD o XSD, di cui vedremo in seguito sintassi e utilizzo) Namespace: un namespace è un riferimento ad un file esterno o ad un URL, nel quale sono contenute informazioni riguardo gli elementi del documento. Sono utili per evitare conflitti, ad esempio se in un documento ci sono due elementi con lo stesso nome. Infatti ogni elemento sarà identificato dal prefisso del namespace. Il prefisso è il testo prima dei due punti nell’esempio sottostante. Tutti gli elementi che faranno riferimento a quel namespace dovranno essere preceduti dal suo prefisso. <es:elementoroot xmlns:es='http://www.w3.org/esempio'> DOCUMENTI BEN-FORMATI E VALIDATI Un documento XML deve essere necessariamente ben-formato (well-formed). Ciò significa che deve rispettare alcune regole sintattiche: il documento XML deve contenere un solo elemento radice ogni elemento deve avere un tag iniziale e un tag finale gli elementi devono essere appropriatamente annidati tutti i valori degli attributi devono essere racchiusi tra virgolette essere case-sensitive Non è invece necessario che un file XML sia anche validato, ma è buona cosa che lo sia. Per essere valicato, un documento XML deve essere ben-formato, deve avere una dichiarazione (DTD o XSD) e la sua struttura deve essere conforme ad essa. XML e Tecnologia Servlet 5 XML PARSER Un parser è un software o un insieme di classi che permettono di leggere un documento XML e rendere i dati contenuti disponibili all’applicazione. Esistono due categorie di parser, validanti e non validanti. I parser validanti permettono di verificare il contenuto del documento attraverso un file esterno che contiene la descrizione della struttura, come può essere un file DTD o XSD, che tratteremo in seguito. Invece i parser non validanti lasciano questo compito all’applicazione che lavora sul documento e controllano solo che il documento sia ben formato. Un parser XML può lavorare su due tipi di interfacce, che rappresentano il documento in due maniere differenti: DOM (document object model): il documento XML è conservato in memoria come un albero, in maniera gerarchica, e permette di navigare nei vari nodi. SAX (simple api for XML): non mantiene il documento in memoria, ma mentre scorre il documento genera un evento ogni volta che incontra un tag. Non è uno standard approvato dal W3C, ma una proposta originariamente per JAVA che poi ha trovato largo uso anche su altre architetture. Hanno entrambi vantaggi e svantaggi, il maggiore di SAX è la sua rapidità e lo scarso utilizzo di memoria, rispetto a DOM è quindi ideale per documenti molto grandi, in quanto non deve contenere tutto in memoria, ed è più vantaggioso per ricercare una singola informazione all’interno di un documento, poiché si può fermare appena trovata. Il difetto principale di SAX è che non è in grado di lavorare sulla struttura del documento (non è validante, non è in grado di creare o eliminare nodi), inoltre non essendo uno standard, non è implementato dai browser. DICHIARAZIONI Come abbiamo detto, i file XML possono contenere una dichiarazione dei dati che saranno al loro interno. Esistono diversi metodi per effettuare questa dichiarazione. I Più comuni sono: Document Type Definition (DTD) XML Schema Definition (XSD) DTD DTD INTERNE ED ESTERNE: La dichiarazione del tipo di documento è l'insieme di regole che controllano la validità del documento XML. Una DTD può essere interna al documento XML oppure esterna, ma queste due possono coesistere, ovvero un file XML può avere una DTD interna che un riferimento ad una esterna; verrà comunque data precedenza a quella interna. La DTD interna va scritta nella parte iniziale del file, una DTD esterna è chiamata tramite un riferimento che indica dove si trova il file DTD più altre eventuali informazioni relative all’autore, all’obiettivo e al linguaggio utilizzato nella DTD. Riferimento ad un file DTD esterno: <!DOCTYPE elementoroot SYSTEM "nomefile.dtd"> XML e Tecnologia Servlet 6 File DTD interno: <!DOCTYPE elementoroot[… definizione del DTD …]> DOCTYPE è l'elemento principale del file XML. ELEMENTI: <!ELEMENT elemento (figlio1,figlio2...)> Definisce un tag di nome elemento, che dovrà contenere al suo interno i tag figlio1, figlio2 ecc. in quell'ordine. I tag figli possono contenere i seguenti caratteri dopo il nome: +: il tag può essere ripetuto ma deve comparire almeno una volta. *: il tag può comparire zero o più volte. ?: il tag è opzionale. Se non è specificato nulla, il tag deve essere presente una e una sola volta. ATTRIBUTI: !ATTLIST elemento attributo1 tipo #opzione attributo2 tipo #opzione ... attributoN tipo #opzione Definisce la lista degli attributi per il tag elemento. E' possibile dichiarare attributi multipli ognuno con il suo tipo e valore. Tipo può avere i seguenti valori: CDATA: il valore è una sequenza di caratteri. Se si presenta nella forma (valore1 | valore2 | valore3…) il valore deve essere uno tra quelli specificati ID: il valore ha un identificativo unico; IDREF: il valore è un ID di un altro elemento; IDREFS: il valore è una lista di ID; NMTOKEN: il valore è un elemento XML valido; NMTOKENS: il valore è una lista di elementi XML validi; ENTITY: il valore è un'entità; ENTITIES: il valore è una lista di entità; NOTATION: Il valore dell’attributo deve fare un riferimento a un’annotazione dichiarata in un altro punto della DTD Opzione può avere i seguenti valori: valore: specifica il valore di default; #REQUIRED: il valore è obbligatorio; #IMPLIED: il valore non è obbligatorio; #FIXED valore: il valore è costante ed equivale al valore specificato subito dopo. XML e Tecnologia Servlet 7 ESEMPIO: L’esempio DTD sottostante implementa una semplicissima libreria. L’elemento root, Libreria, contiene o può contenere diversi elementi di nome libro. Questo elemento contiene un attributo, anno, e due elementi, titolo e autore. <?xml version="1.0" encoding="UTF-8"?> <!ELEMENT Libreria (libro*)> <!ELEMENT libro (titolo, autore)> <!ELEMENT titolo (#PCDATA)> <!ELEMENT autore (#PCDATA)> <!ATTLIST libro anno CDATA #REQUIRED > ENTITA': !ENTITY % nome "valore" Serve a definire il valore di un'entità. Nello stesso file DTD e nel file XML cui fa riferimento il parser leggerà il valore al posto del nome. Riferimento ad un'entità dal file XML: $nome Riferimento ad un'entità all'interno dello stesso file DTD: %nome; IGNORE E INCLUDE: ![IGNORE [porzione DTD]] ![INCLUDE [porzione DTD]] Le parole chiave ignore e include servono a escludere e includere porzioni di codice DTD. Sono utili durante la fase di progettazione. I commenti nei file DTD sono effettuati con la sintassi dell'HTML (<!-- -->). CONSIDERAZIONI: I file DTD hanno però diversi limiti: non sono scritti con le stesse regole dell'XML non consentono di specificare un tipo di dato per gli attributi non premettono di specificare il numero minimo o massimo di occorrenze di un tag in un documento XML e Tecnologia Servlet 8 XSD Per ovviare a questi problemi si utilizzano i files XSD (XML Schema Definition) o XMLSchema che utilizzano la sintassi di XML, sono più flessibili e al contempo più precisi e completi, anche se più complessi. Fino all’aprile 2001 c’erano due versioni di XMLSchema presenti sul mercato: una proposta dal W3C e l’altra proposta da Microsoft, chiamata XDRSchema, da allora la prima è stata accettata come standard. Vediamo la struttura di un file XSD: La prima riga è sempre l’intestazione del documento, in cui è specificato il namespace In questo caso il namespace è quello standard proposto dal W3C <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> ELEMENTI: <xsd: element name="esempio" type="esempioType"/> Questa sintassi dice che l’elemento di nome esempio è di tipo esempioType, che verrà definito in seguito se non è tra i tipi di dato predefiniti presenti nel namespace. Un altro modo è scrivere <xsd: element ref="esempio"/> La clausola ref fa riferimento ad un elemento di nome esempio le cui caratteristiche sono descritte in un'altra parte del documento. TIPI PREDEFINITI: XMLSchema mette a disposizione numerosi tipi di dato predefiniti, tra cui: xsd:string : stringa di caratteri xsd:integer : numero intero xsd:decimal : numero decimale xsd:boolean : valore booleano (true, false oppure 1,0) xsd:date : data xsd:time : ora xsd:uriReference : URL La sintassi per definire un elemento che accetti solo valori interi è: <xs:element name="esempio" type="xsd:integer"> TIPI COMPLESSI: <xsd: complexType name="esempioType"> <xsd:sequence> <xsd:element name=... ... XML e Tecnologia Servlet 9 </xsd:sequence> <xsd:attribute name="att" type="xsd:integer" use=”required”/> </xsd:complexType> Questa è la dichiarazione di un complexType, ovvero di un tag contenente altri tag più un attributo di nome att e di tipo integer. La seconda riga indica il modo in cui devono essere disposti gli elementi e può assumere i seguenti valori: <xs:sequence> : gli elementi devono essere nell’ordine stabilito <xs:choice> : deve essere presente solo uno degli elementi descritti, può anche essere dentro una sequence, anche più volte <xs:all> : gli elementi possono essere in qualunque ordine, presenti 0 o una volta Nell’attributo (va dichiarato dopo gli elementi e non prima) il valore della clausola use può essere optional, nel caso in cui l’attributo non sia necessario o required nel caso opposto. Tutto questo ovviamente vale se non sono stabilite restrizioni dal programmatore. RESTRIZIONI: Le restrizioni sono vincoli che il programmatore impone ai valori dell’attributo o elemento. Riguardano diversi ambiti tra cui, il range dei valori accettabili o il numero di attributi o elementi presenti. Per definire il range occorre partire da una base e fissare i valori massimo e minimo, per esempio: <xsd:simpleType name="mese"> <xsd:restriction base="xsd:integer"> <xsd:minInclusive value="1"/> <xsd:maxInclusive value="12"/> </xsd:restriction> </xsd:simpleType> Questa è la definizione del tipo mese, il quale può assumere solo i valori interi che vanno da 1 a 12, compresi. Se invece fosse stato scritto minExclusive o maxExclusive i valori 1 e 12 non sarebbero stati compresi tra quelli validi. Nel caso abbia un valore non accettabile, il parser XML genererà un errore. <xsd:simpleType name="Provincia"> <xsd:restriction base="xsd:string"> <xsd:enumeration value="RE"/> <xsd:enumeration value="PR"/> <xsd:enumeration value="PC"/> <xsd:enumeration value="MO"/> </xsd:restriction> </xsd:simpleType> Il tipo provincia può assumere solamente i valori che sono specificati nella clausola enumeration. Altre restrizioni sono: length: fissa il numero di caratteri di una stringa minlength e maxlength: lunghezza minima e massima di una stringa fixed: assegna un valore all'attributo o elemento che non è possibile cambiare pattern: è un vincolo sui valori che può assumere una stringa, ad esempio XML e Tecnologia Servlet 10 <pattern value="[0-9]{5}-[A-Z]{4}"/> significa che la stringa deve essere composta da 5 cifre, un trattino e quattro lettere maiuscole. totaldigits: numero massimo di cifre di un numero intero fractiondigits: numero massimo di cifre decimali Le clausole minOccurs e maxOccurs sono invece riferite al numero minimo e massimo di volte cui un elemento può apparire nel file XML. maxOccurs può anche assumere il valore ‘unbounded’ se non si vuole inserire un limite massimo. Le restrizioni sono utili sia per porre limiti o vincoli ad un file XML che per definire nuovi tipi. ESEMPIO: Il file XMLSchema sottostante implementa una libreria come la precedente. E’ evidente la maggiore complessità del documento, ma permette di definire molte più cose, come i tipi di dato o restrizioni. E’ così strutturato: viene prima dichiarato l’elemento root (Libreria) e i suoi elementi sottostanti, in seguito di ogni elemento viene dichiarato il tipo di dato. In questo caso c’è solo un tipo di dato definito dall’utente. <?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="Libreria"> <xsd:complexType> <xsd:sequence> <xsd:element name="libro" minOccurs="0" maxOccurs="unbounded"> <xsd:complexType> <xsd:sequence> <xsd:element name="titolo" type="xsd:string"/> <xsd:element name="autore" type="xsd:string"/> </xsd:sequence> <xsd:attribute name="anno" type="year" use="required"/> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:simpleType name="year"> <xsd:restriction base="xsd:string"> <xsd:pattern value="[0-9]{4}"/> </xsd:restriction> </xsd:simpleType> </xsd:schema> In un documento XML basato sulla grammatica definita in questo schema l’elemento root dovrà essere dichiarato così: <rubrica xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance" xsd:noNamespaceSchemaLocation="rubrica.xsd"> Per vedere se un documento XML rispetta il proprio XMLSchema ci sarà bisogno di un parser validante. XML e Tecnologia Servlet 11 XPATH XPath è un linguaggio messo a disposizione dal W3C per effettuare interrogazioni a database XML. Il linguaggio XPath non è lo stesso di XML. Le espressioni XPath assomigliano a espressioni regolari, eccetto che operano su nodi XML e non su caratteri. Vediamo alcuni esempi: /scuola/classe/alunno Seleziona tutti gli elementi alunno figli di un elemento classe, a sua volta figlio di scuola che è l’elemento root del documento XML //alunno Seleziona tutti gli elementi di nome alunno in qualunque punto del documento si trovino. Il doppio slash significa qualunque profondità, lo slash singolo a partire dall’elemento root e senza slash si intende il percorso a partire dal nodo corrente. //alunno[cognome=”Rossi”] Restituisce tutti gli elementi alunno con al loro interno un elemento cognome il cui valore è uguale a Rossi //alunno[@libretto=”00345”] Restituisce tutti gli elementi di nome alunno che hanno un attributo che si chiama libretto il cui valore è 00345 //classe[alunno] Restituisce tutti gli elementi di nome classe che hanno almeno un elemento di nome alunno /scuola(insegnante|bidello) Restituisce tutti gli elementi insegnante e tutti gli elementi bidello che stanno sotto l’elemento scuola //insegnante[. = “Paganuzzi”] Restituisce tutti gli elementi insegnante contenente il testo Paganuzzi. Il punto prima dell’uguale significa nodo corrente. XPath mette a disposizione anche alcune funzioni sui nodi, vediamo le principali: count(//alunno) Restituisce il numero di elementi di nome alunno in qualunque parte del documento siano. /scuola/classe[position()=3] Restituisce il terzo elemento di nome classe sotto scuola. XML e Tecnologia Servlet 12 /scuola/classe[last()] Restituisce l’ultimo elemento classe. root() Restituisce l’elemento root del documento. FLWOR FLWOR (si legge flower, fiore) è l’acronimo di For, Let, Where, Order by, Return, che è l’elenco dei componenti di un espressione generale. Vedremo il loro significato nel capitolo successivo. XQUERY XQuery (XML Query Language) è un derivato di questo strumento. Ha una sintassi semplice ma il suo maggior difetto è probabilmente la sua scarsa flessibilità. La complessità del codice aumenta in modo esponenziale rispetto alla difficoltà della query da eseguire. FOR La clausola for permette l’iterazione in un documento. La sua sintassi è: for %var [at %indice] in doc(“doc.xml”)/nodo Per tutti i nodi del documento effettua le operazioni che saranno scritte sotto. I termini con prefisso % sono variabili. La prima è ogni volta il nodo selezionato dal ciclo for, indice contiene un intero, che partendo da 1 aumenta ogni volta che si compie il ciclo. Nel nodo possono essere inserite condizioni con la sintassi vista in precedenza. LET La clausola let permette l’assegnamento di una variabile. La sua sintassi è: let %ris := espressione(%parametro) Può essere utilizzato in diversi modi, uno dei più comuni è l’assegnazione di un nodo, o del documento stesso, in questo caso è: let %documento := doc(“prova.xml”) ORDER BY La clausola order by permette di ordinare le tuple della clausola for o i nodi di una let. La sua sintassi, molto semplice, è: [stable] order by $nodo XML e Tecnologia Servlet 13 La clausola stable serve ad indicare che nel caso in cui risultino due valori uguali nell’ordinamento, vengano lasciati nello stesso ordine in cui erano nel documento. Se non viene inserita non verrà stabilito un ordine particolare in caso di uguaglianza. WHERE La clausola where serve a porre delle condizioni. La sua sintassi è: where condizione istruzioni ... La clausola where assomiglia all’if (senza l’else però), in quanto esegue le istruzioni sotto di essa solo nel caso la condizione risulti vera. La clausola where può confrontare nodi XML, stringhe, valori interi o funzioni e può essere qualsiasi cosa restituisca un valore boolean, come una funzione o una condizione (=,<,>,>=). RETURN La clausola return specifica il valore di ritorno. Se dentro una funzione è il valore ritornato, se dentro il for principale o sotto una let è il valore ritornato dalla query, che è generalmente un nuovo documento XML. Vediamo alcuni esempi che saranno basati su questo file XML di nome test.xml: <?xml version="1.0" encoding="UTF-8"?> <todolist> <item> <number>1</number> <priority>6</priority> <description>Leggere la posta</description> <state>2</state> </item> <item> <number>2</number> <priority>9</priority> <description>Riunione</description> <state>2</state> </item> <item> <number>3</number> <priority>8</priority> <description>Andare a correre nel parco</description> <state>1</state> </item> <item> <number>4</number> <priority>5</priority> <description>Rapinare banche</description> <state>2</state> </item> <item> <number>5</number> <priority>7</priority> <description>Cena di classe</description> <state>1</state> </item> </todolist> XML e Tecnologia Servlet 14 ESEMPIO 1: (:esempio di query:) xquery version "1.0"; <prova> { for $b in doc("test.xml")/todolist/item where $b/state = 1 return <attivita> {$b/description} </attivita> } </prova> La prima riga è un commento, che va incluso tra i simboli (: e :). Il significato di questo listato è il seguente: per ogni elemento item presente nel file test.xml con l’attributo state = 1, inserisce nel documento di output l’elemento descrizione sotto il tag attivita. L’elemento root del documento è prova. Il risultato è il seguente: <?xml version="1.0" encoding="UTF-8"?> <prova> <attivita> <description>Andare a correre nel parco</description> </attivita> <attivita> <description>Cena di classe</description> </attivita> </prova> ESEMPIO 2: xquery version "1.0"; declare variable $x external; <prova> { for $b in doc("test.xml")/todolist/item return <attivita> { if ($b/state = $x) then <svolta> {$b/description} </svolta> else <dasvolgere> {$b/description} </dasvolgere> } </attivita> XML e Tecnologia Servlet 15 } </prova> In questo esempio viene utilizzato un parametro, la dichiarazione delle variabili è poco differente: declare variable $nome {valore predefinito}; I parametri vengono passati da riga di comando con la sintassi nome=valore, dopo il nome della query. E’ presente il costrutto if-then-else. Nessuna delle tre clausole può mancare. Se l’else non deve fare nulla si può scrivere else (). Il risultato della query è il seguente, se il parametro passato ha valore 1: <?xml version="1.0" encoding="UTF-8"?> <prova> <attivita> <dasvolgere> <description>Leggere la posta</description> </dasvolgere> </attivita> <attivita> <dasvolgere> <description>Riunione</description> </dasvolgere> </attivita> <attivita> <svolta> <description>Andare a correre nel parco</description> </svolta> </attivita> <attivita> <dasvolgere> <description>Rapinare banche</description> </dasvolgere> </attivita> <attivita> <svolta> <description>Cena di classe</description> </svolta> </attivita> </prova> Per fare queste prove e la successiva abbiamo usato Saxon 7.8, uno strumento freeware che permette l’utilizzo di XQuery compilando le query grazie a delle librerie di java fornite. INTERROGAZIONE ORARIO SCOLASTICO: Il seguente è il listato di un file batch (Orario.bat) che può eseguire due interrogazioni all’interno del database XML dell’orario scolastico, orario di un prof dato la matricola e l’orario di una classe dato il suo codice. Il risultato è stampato a video come documento XML. echo off if "%1" == "p" goto PROF if "%1" == "c" goto CLASSI echo "Utilizzo del batch: Orario p <matricola> per l'orario di un professore, Orario c <classe> per l'orario di una classe" XML e Tecnologia Servlet 16 goto FINE :PROF C:\j2sdk1.4.2_02\bin\java -cp saxon7.jar net.sf.saxon.Query interrogazioneprof.xq "mat=%2" goto FINE :CLASSI C:\j2sdk1.4.2_02\bin\java -cp saxon7.jar net.sf.saxon.Query interrogazioneclassi.xq "nomeclasse=%2" :FINE Quindi la sintassi per chiamare la query è per i professori: Orario p <matricola> Per le classi: Orario c <classe> Le interrogazioni sono nei files interrogazioneprof.xq e interrogazioneclassi.xq: declare variable $mat external; <result> { for $b in doc("OrarioScolastico.xml")/OrarioScolastico/Orario where $b/MATRICOLA=$mat return <orario> { $b/CLASSE,$b/ORA } </orario> } </result> declare variable $nomeclasse external; <result> { for $b in doc("OrarioScolastico.xml")/OrarioScolastico/Orario where $b/CLASSE=fn:upper-case($nomeclasse) return <orario> { $b/MATRICOLA,$b/ORA } </orario> } </result> Sono interrogazioni molto semplici che ricevono un parametro e lo confrontano con l’elemento matricola o classe. L’unica novità è la presenza di una funzione. La sintassi della funzione è molto semplice: <risultato>=<prefisso>:<nomefunzione>(<parametri>) Il prefisso è generalmente fn (come nell’esempio) oppure xslt. XML e Tecnologia Servlet 17 XSL FOGLI DI STILE I fogli di stile permettono la separazione della forma dal contenuto. Il concetto di foglio di stile è quello di creare un documento separato che contenga tutte le informazioni necessarie per la formattazione o la trasformazione di qualsiasi tipo di dati a cui si decida di applicarlo. I PRINCIPALI VANTAGGI DEI FOGLI DI STILE Uno dei vantaggi principali sono il risparmio di tempo e la maggior praticità di gestione del sito (se si desidera infatti modificare l'aspetto di un sito web non è necessario effettuare le correzioni in ogni pagina ma è sufficiente modificare il foglio di stile per rendere effettivi i cambiamenti). Un altro è la personalizzazione grafica, in quanto l’aspetto degli elementi è modificabile; inoltre è possibile servirsi dell’utilizzo di un unico foglio di stile per formattare più documenti e si ha anche la possibilità di adattare la formattazione al tipo di utente e device che ha accesso ai dati. I fogli di stile oggi utilizzati sono essenzialmente di tre tipi: CSS (Cascading Style Sheet), utilizzati soprattutto per HTML; XSL (Extensible Stylesheet Language), utilizzati per formattare un documento XML destinato alla stampa; XSLT (Extensible Shylesheet Language Transformation), utilizzati per la trasformazione di un documento XML. UN NUOVO LINGUAGGIO… XSL XSL è un nuovo linguaggio creato per definire fogli di stile che definiscano la presentazione del documento. Il suo utilizzo implica l’esistenza di un processore XSL che codifica la sorgente XML nel modo definito dal foglio di stile. XSL è certamente uno dei più importanti linguaggi standard del W3C. Esso risulta composto di tre parti, ciascuna delle quali rientra nella specifica XSL 1.0, pubblicata nell'ottobre 2001: XSLT: ( trasformation language) è un linguaggio che consente di trasformare documenti XML in altri formati; Xpath: definisce espressioni e metodi per accedere ai nodi di un documento XML (è trattato più approfonditamente in altre parti della relazione); XSL:FO (Formatting Object): usato per formattare in maniera precisa un oggetto trasformato. XSLT Un foglio di stile XSLT è un documento XML valido e ben formato. Fornisce un meccanismo per trasformare un documento XML in un altro. Una trasformazione può essere così schematizzata: XML e Tecnologia Servlet 18 XSLT consente di trasformare un albero iniziale XML (source tree) in un altro albero (result tree) i cui elementi possono differire molto da quelli iniziali. Generalmente viene utilizzato per operare trasformazioni tra linguaggi diversi (ad esempio da XML a HTML) o per codificare in modo automatico un documento basato su un linguaggio troppo complesso (ad esempio MathML). E’ quindi sostanzialmente definibile come un linguaggio ad alto livello, in grado di navigare per la struttura del documento e di accedere ai nodi. I fogli di stile XSLT hanno una struttura modulare per permettere di riutilizzare i moduli, ricombinandoli in modo differente a seconda delle necessità. Un foglio di stile XSLT si apre con una dichiarazione che identifica il tipo di documento e lo spazio dei nomi (namespace) utilizzato: <xsl:stylesheet xmlns:xsl=http://www.w3.org/1999/XSL/Transform version=”1.0”> Dopo la dichiarazione iniziale si trovano gli elementi di primo livello. L’elemento di primo livello deve necessariamente essere uno tra: <xsl:attribute-set> <xsl:decimal format> <xsl:import> <xsl:include> <xsl:key> <xsl:namespace-alias> <xsl:output> <xsl:param> <xsl:preserve-space> <xsl:strip-space> <xsl:template> <xsl:variable> E’ anche possibile avere degli elementi di primo livello definiti da sviluppatori o dagli utenti. In generali questo tipo di elementi, che si riferiscono a uno spazio dei nomi differente, sono definiti dagli sviluppatori di processori XSL, che creano degli elementi proprietari utili per eseguire determinate funzioni complesse. Il processo di trasformazione avviene tramite l’applicazione di regole agli elementi dell’albero. Ogni regola è definita dell’elemento <xsl:template> che possiede un attributo match che identifica l’elemento dell’albero a cui va applicata la regola. Ogni regola possiede poi un corpo , chiamato template body, nel quale sono espresse le istruzioni da eseguire e un elemento di chiusura (</xsl:template>). Ecco alcuni elementi utilizzati per definire le regole e controllare il modo in cui sono invocate: <xsl:template> <xsl:apply-template> <xsl:call-template> i seguenti elementi definiscono la struttura del foglio di stile: <xsl:stylesheet> <xsl:include> <xsl:import> XML e Tecnologia Servlet 19 altri elementi vengono utilizzati per generare un output: <xsl:value-of> <xsl:element> <xsl:attribute> <xsl:comment> <xsl:processing-instruction> <xsl:text> elementi utilizzati per definire variabili e parametri: <xsl:variable> <xsl:param> <xsl:with-param> elementi utilizzati per copiare informazioni dal documento sorgente al documento destinazione: <xsl:copy> <xsl:copy.of> elementi utilizzati per creare istruzioni e processi condizionali e iterazioni: <xsl:if> <xsl:choose> <xsl:when> <xsl:otherwise> <xsl:for-each> elementi utilizzati per controllare l’ordine e la numerazione: <xsl:sort> <xsl:number> elementi utilizzati per controllare il formato del documento output: <xsl:output> XSL-FO XSL Formatting Object è stato creato per fornire agli sviluppatori uno strumento agile per controllare in modo preciso l’impaginazione e la disposizione della pagina, senza l’utilizzo di elementi complessi (ad esempio i frame). XSL:fo è simile a CSS per le proprietà utilizzate, anche se spesso le estende per garantire maggiore controllo. Scopi del linguaggio: definire la fase di formattazione; definire un vocabolario di elementi di formattazione indipendenti dal tipo di supporto utilizzato per l’output. XML e Tecnologia Servlet 20 Il legame tra le due definizioni è ovviamente molto stretto in quanto la fase di formattazione interpreta l’albero che risulta dall’eventuale trasformazione in base alla semantica degli oggetti di formattazione che lo costituiscono. Esistono quattro sottoclassi di proprietà XSL:FO: Proprietà interamente prese da CSS. Proprietà CSS estese con altri valori. Proprietà CSS suddivise. Proprietà originali XSL. COME LAVORA XSL Dopo aver fatto le opportune considerazioni vediamo, tramite un esempio, come lavora realmente xsl. Per i seguenti esempi verrà utilizzato il file xml “Studenti.xml” il cui contenuto è il seguente: <?xml version='1.0'?> <?xml-stylesheet type='text/xsl' href='STUDENTEPROVA.xsl'?> <studenti> <studente matricola="1"> <cognome>rossi</cognome> <nome>mario</nome> <nascita>17/07/1974</nascita> <esame> <data> 25/05/1998</data> <materia> analisi</materia> <voto> 28</voto> </esame> </studente> <studente matricola="2"> <cognome>bianchi</cognome> <nome>annalisa</nome> <nascita>28/02/1976</nascita> <esame> <data> 25/05/1998</data> <materia> fisica</materia> <voto> 30</voto> </esame> </studente> <studente matricola="3"> <cognome>verdi</cognome> <nome>antonio</nome> <nascita>16/01/1979</nascita> <esame> <data> 12/04/1999</data> <materia> algebra</materia> <voto> 22</voto> </esame> </studente> </studenti> XML e Tecnologia Servlet 21 La struttura di un file XSL tipica intestazione xsl utilizzo della clausola for-each che esegue una certa istruzione per ogni elemento del tag studenti utilizzo dell’istruzione value-of che visualizza in output il valore di un elemento Qui di seguito è riportata la pagina web che viene generata al lancio con Internet Explorer del file xml. In realtà è il file xsl a cui fa riferimento che permette di visualizzare i dati sotto forma di tabella. JAVA E XML Il legame tra XML e Java è sicuramente fortissimo. Così come Java permette di scrivere codice in modo che sia indipendente dall’hardware e dal sistema operativo, XML fa la stessa cosa con i dati. Infatti, la maggior parte dei parser XML è proprio scritto in Java. E’ quindi ovvio l’interesse che la Sun ha mostrato per XML. Ha creato uno standard, basato sulle librerie JAX (Java API for XML), in modo da evitare al programmatore lo sforzo di creare classi proprie e impedire una grossa confusione sugli standard. Esistono però molte altre librerie per l’analisi sui documenti XML. Tra queste ci soffermeremo su JDOM. XML e Tecnologia Servlet 22 JDOM JDOM è una API open source in grado di far interagire Java e XML che interagisce sia con i parser SAX che parser DOM. DOCUMENTO In JDOM un documento XML è rappresentato da un’ istanza della classe org.jdom.Document. Ha diversi costruttori, il più utile riceve in ingresso un’istanza della classe Element, rappresentante l’elemento root. PARSING Il parsing dei documenti XML è ottenuto tramite le classi SAXBuilder e DOMBuilder che permettono di costruire il documento con i due metodi di parsing. Ricevono in ingresso nel costruttore un valore booleano che dice se eseguire o no la validazione del documento. Il metodo principale è build, che riceve in ingresso un File o un InputSource e restituisce un oggetto della classe Document o della classe Element. Ad esempio: SAXBuilder builder = new SAXBuilder(true); Document doc = builder.build(new File(“esempio.xml”); Queste due righe di codice servono a fare il parsing validante (perché builder riceve in ingresso true), se riesce assegna il risultato al documento doc, altrimenti genera un’eccezione org.jdom.input.JDOMParseException. LETTURA DI UN DOCUMENTO XML Per scorrere all’interno di un documento XML, JDOM utilizza le classi Element, Attribute, List e Iterator. Element rappresenta un nodo del documento XML Element e = doc.getRootElement() In questo caso viene assegnato all’elemento root del Document doc. Per scorrere all’interno del documento si possono utilizzare i seguenti metodi: getChild(nome): ritorna il primo elemento figlio con quel nome getChildren(): restituisce un’istanza della classe List contenente tutti i nodi figli dell’elemento getChildren(nome): restituisce tutti i nodi figli dell’elemento con quel determinato nome getValue(): restituisce una stringa con il valore dell’elemento getAttribute(nome): restituisce un oggetto di tipo Attribute getAttributeValue(nome): restituisce il valore dell’attributo richiesto sotto forma di stringa La classe List non è propria di JDOM ma risulta molto utile per scorrere i documenti XML, abbiamo infatti visto che alcuni metodi di Element restituiscono una List, che diventa a tutti gli effetti un array di Element. XML e Tecnologia Servlet 23 La classe Iterator (java.util.Iterator) permette di scorrere una List Iterator i = list.iterator(); Ora è possibile scorrere la lista, ovvero la sequenza di Element, tramite l’Iterator: while(i.hasNext()) { e=(Element)i.next(); ...operazioni sull’elemento... } Una classe utile è XMLOutputter, in grado di stampare i nodi rappresentati dagli oggetti Element interamente, ovvero comprendenti tutti i caratteri, tag compresi. Quindi utilizzare il metodo outputString sull’elemento root significa stampare l’intero documento XML. La classe Attribute rappresenta un attributo di un elemento XML. ESEMPIO DI LETTURA DI UN DOCUMENTO: Per gli esempi utilizzeremo questo documento XML che rappresenta l’orario scolastico di una classe: <?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="provaorario.xsl"?> <productDB> <orario> <ora name="1 ora"></ora> <Lunedi name="Matematica"></Lunedi> <Martedi name="Statistica"></Martedi> <Mercoledi name="Inglese"></Mercoledi> <Giovedi name="Matematica"></Giovedi> <Venerdi name="Ginnastica"></Venerdi> <Sabato name="Sistemi"></Sabato> </orario> <orario> <ora name="2 ora"></ora> <Lunedi name="Inglese"></Lunedi> <Martedi name="Italiano"></Martedi> <Mercoledi name="Elettronica"></Mercoledi> <Giovedi name="Sistemi"></Giovedi> <Venerdi name="Informatica"></Venerdi> <Sabato name="Sistemi"></Sabato> </orario> <orario> <ora name="3 ora"></ora> <Lunedi name="Italiano"></Lunedi> <Martedi name="Storia"></Martedi> <Mercoledi name="Religione"></Mercoledi> <Giovedi name="Informatica"></Giovedi> <Venerdi name="Informatica"></Venerdi> <Sabato name="Storia"></Sabato> </orario> <orario> <ora name="4 ora"></ora> <Lunedi name="Italiano"></Lunedi> <Martedi name="Inglese"></Martedi> <Mercoledi name="Statistica"></Mercoledi> <Giovedi name="Informatica"></Giovedi> <Venerdi name="Sistemi"></Venerdi> <Sabato name="Elettronica"></Sabato> XML e Tecnologia Servlet 24 </orario> <orario> <ora name="5 ora"></ora> <Lunedi name="Statistica"></Lunedi> <Martedi name="Iformatica"></Martedi> <Mercoledi name="Matematica"></Mercoledi> <Giovedi name="Elettronica"></Giovedi> <Venerdi name="Sistemi"></Venerdi> <Sabato name="Elettronica"></Sabato> </orario> <orario> <ora name="6 ora"></ora> <Lunedi name="Ginnastica"></Lunedi> <Martedi name="Informatica"></Martedi> <Mercoledi name="Matematica"></Mercoledi> <Giovedi name="Elettronica"></Giovedi> <Venerdi name="Sistemi"></Venerdi> <Sabato name="Elettronica"></Sabato> </orario> </productDB> Questo è un esempio di classe Java per eseguire un interrogazione: import import import import import org.jdom.*; org.jdom.input.SAXBuilder; java.util.*; java.io.File; itis.Tastiera; public class LetturaOrario { public static void main(String args[]) { try { String s,in; SAXBuilder builder=new SAXBuilder(); Document doc = builder.build(new File("orario.xml")); Element e1,e2; e1=doc.getRootElement(); List l1,l2; Iterator i1,i2; l1=e1.getChildren(); i1=l1.iterator(); System.out.print("Inserisci la materia da ricercare: "); in=Tastiera.leggiStringa(); while(i1.hasNext()) { //scorre gli elementi item e1=(Element)i1.next(); l2=e1.getChildren(); i2=l2.iterator(); while(i2.hasNext()) { //scorre i figli di item e2=(Element)i2.next(); s=e2.getAttributeValue("name"); if(s.compareTo(in)==0) { //se è quel che sto cercando s=e1.getChild("ora").getAttributeValue("name"); System.out.print(s + " "); s=e2.getName(); System.out.println(s); } } } } catch(Exception ex) { System.out.println(ex); } } } XML e Tecnologia Servlet 25 Tramite la classe Tastiera creata per semplificare l’input e l’output in modalità testuale, il programma richiede all’utente la materia da ricercare. La parte principale della classe è composta da due cicli while, l’uno dentro l’altro. Il primo scorre gli elementi item, il secondo scorre al’interno tutti i suoi figli (ora, lunedì, martedì…) e confronta i loro valori con il valore inserito dall’utente. In caso di successo, pubblica l’ora e il giorno. ESEMPIO DI MODIFICA DI UN DOCUMENTO: import import import import import import import org.jdom.*; org.jdom.input.SAXBuilder; org.jdom.output.XMLOutputter; java.util.*; java.io.File; java.io.*; itis.Tastiera; public class Modifica { public static void main(String args[]) { try { String giorno,ora,materia; SAXBuilder builder=new SAXBuilder(); Document doc = builder.build(new File("orario.xml")); Element e,scorre; List l; Iterator i; XMLOutputter outputter = new XMLOutputter(); System.out.print("Giorno: "); giorno=Tastiera.leggiStringa(); System.out.print("Ora: "); ora=Tastiera.leggiStringa(); System.out.print("Materia: "); materia=Tastiera.leggiStringa(); e=doc.getRootElement(); l=e.getChildren(); i=l.iterator(); while(i.hasNext()) { e=(Element)i.next(); if(e.getChild("ora").getAttributeValue("name").compareTo(ora+" ora")==0) { e.getChild(giorno).setAttribute("name",materia); System.out.println("Modifica effettuata"); } } outputter.output(doc,new FileOutputStream("orario.xml")); } catch(Exception ex) { System.out.println(ex); } } } La classe qui sopra serve a modificare il documento XML visto in precedenza. Richiede all’utente il giorno e l’ora da modificare, e il valore che va inserito. Il ciclo while scorre gli elementi item, e quando trova l’ora selezionata modifica l’attributo dell’elemento con il nome uguale al giorno inserito dall’utente. Alla fine, riscrive il documento su file grazie ad un’istanza della classe XMLOutputter. Il metodo output riceve in ingresso un oggetto Document e uno stream di output, come ad esempio FileOutputStream. XML e Tecnologia Servlet 26 TRASFERIMENTO DATABASE MDB IN XML Il trasferimento dei database Orario, Classi, Personale e Aule da .mdb a .xml è stato eseguito attraverso un interrogazione SQL, in un programma scritto in Visual Basic, al database “itis” situato sul server Informatca00. Prima di giungere a questa soluzione abbiamo provato altri tipi di soluzione ma ogni volta non riuscivamo ad ottenere il risultato prefissato o non riuscivamo proprio ad eseguire una prova, a causa di problemi di diritti, problemi di sintassi del programma o un utilizzo del codice errato. L’obbiettivo era trasformare automaticamente un database Access in un database Xml senza dover apportare nessuna modifica a mano. Il primo tentativo è stato effettuato con Query Analyzer di SQL Server: dopo aver eseguito la connessione alla macchina server Cuore20, con la query “Select * From Personale For Xml Auto” riusciamo a trasformare i dati in un formato Xml, purtroppo non si riesce a salvare i dati integri poiché il risultato viene stampato malamente, una riga contiene al massimo 256 caratteri, tutto ciò che viene dopo viene approssimato con tre puntini di sospensione e si perdono alcuni dati. Dopo aver abbandonato l’utilizzo di Query Analyzer abbiamo scritto una pagina Asp che aprisse il database ed eseguisse l’interrogazione per trasformare il database situato sul server. Il trasferimento dei dati è stato eseguito tramite l’uso di oggetti della classe ADO. Abbiamo utilizzato un Command e/o un Recordset. Un oggetto Recordset rappresenta i record di un database o i record che risultano dall'esecuzione di una query. Gli oggetti Recordset consentono di manipolare i dati in un database a livello di record. Per oggetto Command si intende una definizione di un comando specifico da eseguire su una fonte dati. Un oggetto Command viene utilizzato per eseguire query su un database, per eseguire un’operazione su gruppi o per modificare la struttura di un database. ADO è una classe XML e Tecnologia Servlet 27 che fornisce gli oggetti utilizzati, e consente di gestire il modello Microsoft di accesso ai dati, permettendo di accedere con prestazioni elevate a qualsiasi fonte dati. Un oggetto Connection è semplicemente una stringa che permette di stabilire una connessione aperta con un database. Prima di eseguire la query bisogna impostare la relativa proprietà ActiveConnection su una stringa di connessione valida. Se alla stessa connessione vengono tuttavia associati più oggetti Command sarà necessario creare e aprire esplicitamente un oggetto Connection, in modo da assegnarlo a una variabile oggetto. Se la proprietà ActiveConnection degli oggetti Command non viene impostata sulla variabile oggetto, ADO creerà un nuovo oggetto Connection per ciascun oggetto Command anche se si utilizza la stessa stringa di connessione. In questo programma abbiamo effettuato l’accesso al database tramite un Command, poi il risultato della query è stato rimandato su un DomDocument, per poi salvarli in un file Xml. strQuery = "<root><sql:query xmlns:sql='urn:schemas-microsoft-com:xml-sql'> " strQuery = "SELECT * FROM Personale FOR XML AUTO" strQuery = strQuery & "</sql:query></root>" cmdCurrent.CommandText = strQuery cmdCurrent.Dialect = "{5D531CB2-E6Ed-11D2-B252- 00C04F681B71}" cmdCurrent.Properties("Output Stream") = Dom cmdCurrent.Execute , , 1024 Dom.Save "Prova.xml" Le prime due righe servono per definire lo schema del database xml. La pagina è stata messa nella apposita cartella sul server Informativa00 per poi essere eseguita con il browser Internet Explorer. Il file salvato sfortunatamente è risultato vuoto e così abbiamo abbandonato anche questa soluzione. Abbiamo scritto un programma in Visual Basic, molto semplice, che apriva i database attraverso un Recordset e, selezionando la proiezione del contenuto del database, abbiamo salvato il risultato con l’opzione “adPersistXML”. Ogni pulsante apre il database con il rispettivo nome (Personale, Aule, Classi, Orario) e lo trasferisce in un file Xml. Esempio listato: Set objADORS = New ADODB.Recordset objADORS.Open "SELECT * From Personale", "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=itis;Data Source=INFORMATICA00" objADORS.Save "C:\Documents and Settings\sgaspare\Documenti\xml\Nuova cartella\Personale.xml", adPersistXML XML e Tecnologia Servlet 28 objADORS.Close Set objADORS = Nothing Il risultato sono quattro database Xml aventi uno schema “row”. Esempio: <rs:data> <z:row IDAULA='1'/> <z:row IDAULA='12'/> <z:row IDAULA='3'/> … Cosi abbiamo fatto un ulteriore programma che riuscisse a trasferire i database in Xml in modo che avessero uno schema differente: ad Elements. Quest’ultimo programma è costituito da un solo pulsante. Una volta premuto il pulsante il programma chiama una funzione che apre uno alla volta i database tramite un oggetto Command e, dopo avere settato alcuni parametri, dichiaro la query di interrogazione e la eseguo per ogni database, concluso il trasferimento il programma si chiude automaticamente. Il risultato del esecuzione del programma sono quattro database xml uniti poi in solo file per creare un database unico. L’interrogazione sql è una semplice query che seleziona tutti gli elementi del database e con un istruzione finale “For Xml Auto ,Elements” trasforma automaticamente la proiezione dell’interrogazione in xml nel formato predefinito. Il risultato viene poi salvato in un file con l’istruzione “objADOStream.SaveToFile nomefile.xml”. Esempio listato: Private Private Private Private WithEvents WithEvents WithEvents WithEvents Conn As ADODB.Connection ConnRemota As ADODB.Connection RecoLocale As ADODB.Recordset RecoRemoto As ADODB.Recordset Private Sub Trasferisci_Click() Main 'eseguo la funzione MsgBox "finito" Unload Me 'ed chiudo il programma immediatamente End Sub Function Main() Dim objADOStream Dim objADOCmd 'dichiaro un puntatore per aprire il database 'dichiaro una variabile per interrogare il database Const adExecuteStream = 1024 Set objADOCmd = CreateObject("ADODB.Command") Set objADOStream = CreateObject("ADODB.Stream") objADOStream.Type = 2 'setto la costante = Text objADOStream.Open 'con dei msgbox mostro a video a che punto sono del programma MsgBox "inizio" XML e Tecnologia Servlet 29 'attivo una connessione a INFORMATICA00 al database itis objADOCmd.ActiveConnection = "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=itis;Data Source=INFORMATICA00" MsgBox "activeconnection" objADOCmd.Dialect = "{5D531CB2-E6Ed-11D2-B252-00C04F681B71}" 'trasferisco il Personale MsgBox "trasferimento personale" 'immetto la stringa di query per trasferire il database Personale objADOCmd.CommandText = "<Personale xmlns:sql='urn:schemas-microsoft-com:xmlsql'>" & _ "<sql:query>" & _ "SELECT * FROM Personale FOR XML AUTO ,ELEMENTS" & _ "</sql:query>" & _ "</Personale>" 'al Command che utilizzo dico che ciò che risulta dall'esecuzione 'sarà mandato all'oggetto "objADOStream" objADOCmd.Properties("Output Stream") = objADOStream 'eseguo l'interrogazione objADOCmd.Execute , , adExecuteStream 'e salvo il risultato in un file xml objADOStream.SaveToFile "C:\Documents and Settings\sgaspare\Documenti\xml\trasforma elements\Personale.xml" objADOStream.Close Set objADOStream = Nothing Il risultato di quest’applicazione è un database ben formato con le informazioni suddivise in elementi. Esempio: <Aule> <IDAULA>1</IDAULA> </Aule> <Aule> <IDAULA>12</IDAULA> </Aule> EDITOR XML REALIZZAZIONE E FUNZIONALITÀ Un altro punto fondamentale della nostra tesina è stata la realizzazione di de “The Real XML Editor” ovvero un editor di file XSL ed XML è stato utilizzato l’ambiente di sviluppo Visual Basic 6.0 e che è stato realizzato interamente da noi. Questo programma permette ai più esperti di creare dei file XML ed XSL in modo semplice ed immediato ma anche agli utenti alle prime armi di acquistare dimestichezza con i due linguaggi in questione tramite la “creazione guidata”; questo editor consente sia di aprire più file già esistenti per modificarli, sia di creare dei nuovi documenti attraverso il menù file e i suoi appositi form. XML e Tecnologia Servlet 30 L’EDITOR IN ESECUZIONE Ecco come appare la finestra principale in esecuzione: La gestione dei nuovi documenti avviene dal menu File Tramite questa TabStrip è possibile gestire più file contemporaneamente Ecco come viene visualizzato il file XML Come si può vedere sono presenti anche dei pulsanti che facilitano l’interazione con i documenti. Questi bottoni servono per inserire automaticamente un riferimento a file xsl (nel caso di file xml), inserire un elemento con il suo corrispettivo valore, inserire nel documento (nel caso sia xsl) la tipica intestazione di questo linguaggio e infine di inserire un “header” ovvero un’intestazione che riguarda il nome del file. Appena il programma viene caricato vengono visualizzati i primi form di presentazione nei quali è già possibile scegliere quale sarà l’attività che si vuole svolgere (apertura o creazione di un nuovo file), e dai quali è possibile accedere alla finestra principale. XML e Tecnologia Servlet 31 Form di presentazione: Form di selezione dell’attività: UNO SGUARDO PIÙ IN PROFONDITÀ… Tramite la voce “Nuovo” dal menu file oppure dal form mostrato poco sopra è possibile accedere ad un altro form che consente di selezionare il tipo di file da creare (se xsl o xml): Per i file xml, nel caso che all’ingresso si abbia selezionato la voce “creazione tramite Wizard” il nuovo file sarà creato passo passo attraverso delle inputbox nelle quali bisognerà inserire i valori desiderati in modo corretto. La funzione che segue è una porzione di quella utilizzata per tale scopo: Public Sub creazioneguidataxml () ' CONSENTE TRAMITE UNA SERIE DI ISTRUZIONI DI CREARE PASSO PASSO UN FILE XML Dim j As Integer Dim numeroelementi As Integer Dim numeroradici As Integer Dim nomeradice As String Dim elemento(100) As String Dim valoreelemento As String Dim nodoprincipale As String Dim stringa As String XML e Tecnologia Servlet 32 Dim h As Integer Dim risultato As String ' inizio del percorso guidato per la creazione del nuovo documento xml On Error GoTo errori stringa = EditorText(NumFileAperti) nodoprincipale = InputBox("Inserire il nome del nodo radice (es.:libreria):", "NOME NODO PRINCIPALE") stringa = stringa + vbCrLf + "<" + nodoprincipale + ">" nomeradice = InputBox("Inserire il nome dell'elemento principale(es.:libro):", "NOME RADICE") numeroradici = CInt(InputBox("Inserire il numero degli elementi principali:", "NUMERO RADICI")) numeroelementi = CInt(InputBox("Inserire il numero dei sottoelementi:", "NUMERO ELEMENTI")) For h = 0 To numeroradici - 1 stringa = stringa + vbCrLf + "<" + nomeradice + ">" + vbCrLf For j = 0 To numeroelementi - 1 If h = 0 Then elemento(j) = InputBox("Inserire il nome del sottoelemento (es.:titolo o autore o anno):", "NOME ELEMENTO") End If valoreelemento = InputBox("Inserire il valore del sottoelemento (es.:La locandiera o Goldoni o 1795):", "VALORE ELEMENTI") stringa = stringa + "<" + elemento(j) + ">" + valoreelemento + "</" + elemento(j) + ">" + vbCrLf Next j stringa = stringa + "</" + nomeradice + ">" + vbCrLf Next h stringa = stringa + "</" + nodoprincipale + ">" EditorText(NumFileAperti) = stringa Exit Sub errori: EditorText(NumFileAperti) = IntestazioneXml End sub Nel caso dei file xsl invece è presente un altro form che consente di specificare ulteriormente il tipo di file xsl, se normale o interrogativo (entrambi possono essere sottoforma di tabella): Anche i questo caso verrà chiamata l’apposita funzione che creerà passo passo un nuovo foglio di stile xsl attraverso una serie di inputbox. XML e Tecnologia Servlet 33 I RISULTATI DELL’EDITOR Qui di seguito verranno riportati l’output di alcuni file, sia xml che xsl, che sono stati realizzati interamente con questo editor: Il file precedente è il file “studente.xml” che fa riferimento, per la sua visualizzazione, al file “studente.xsl”, che inserisce ogni elemento del file xml nella tabella. La struttura del file è la seguente: <?xml version='1.0'?> <xsl:stylesheet xmlns:xsl='http://www.w3.org/TR/WD-xsl'> <xsl:template match='/'> <html> <body> <table border='2'> <tr bgcolor='red'> <td> <b>MATRICOLA</b></td> <td><b>COGNOME</b></td> <td><b>NOME</b></td> <td><b>NASCITA</b></td> </tr> <xsl:for-each select='studenti/studente'> <tr> <td><xsl:value-of select='@matricola'/></td> <td><xsl:value-of select='cognome'/></td> <td><xsl:value-of select='nome'/></td> <td><xsl:value-of select='nascita'/></td> </tr> </xsl:for-each> </table> </body> </html> </xsl:template> </xsl:stylesheet> Il file riportato qui di seguito è sempre il file studente.xml ma che ora fa riferimento per la sua visualizzazione al file studente2.xsl. Questo file non è un normale foglio di stile xsl ma effettua una vera e propria interrogazione sul documento xml in questione ovvero visualizza in ordine alfabetico decrescente (in base al cognome) tutte le informazioni (matricola, cognome, nome e nascita) solo degli studenti con matricola uguale a due. Il contenuto del file studente2.xsl è il seguente: <?xml version='1.0'?> <xsl:stylesheet xmlns:xsl='http://www.w3.org/TR/WD-xsl'> XML e Tecnologia Servlet 34 <xsl:template match='/'> <html> <body> <table border='2'> <tr bgcolor='blue'> <td> <b>MATRICOLA</b></td> <td><b>COGNOME</b></td> <td><b>NOME</b></td> <td><b>NASCITA</b></td> </tr> <xsl:for-each select='studenti/studente [ @matricola cognome'> <tr> <td><xsl:value-of select='@matricola'/></td> <td><xsl:value-of select='cognome'/></td> <td><xsl:value-of select='nome'/></td> <td><xsl:value-of select='nascita'/></td> </tr> </xsl:for-each> </table> </body> </html> </xsl:template> </xsl:stylesheet> = "2" ]' order-by='- Tutti i file utilizzati e molti altri sono allegati nell’installazione de “The Real XML Editor”. TECNOLOGIA SERVLET L’ARCHITETTURA CLIENT/SERVER L’architettura Client/Server (C/S) è quella tecnologia che permette a diversi calcolatori collegati in rete di utilizzare e condividere delle risorse. In questa situazione, i calcolatori così come le risorse sono distribuite su un’area senza estensioni predefinite e sono collegati tra loro per formare le reti, che possono essere locali (LAN) , estese su un’area metropolitana (MAN) oppure molto più grandi e comprendenti aree geografiche estese (WAN). Alla base dell’architettura Client/Server c’è il concetto di condivisione delle risorse (sia HW che SW) e si possono distinguere due entità che sono collegate tra loro e comunicano usando un’apposito protocollo: Il server: il computer che mette a disposizione le risorse; Il client: il computer che richiede e utilizza la risorsa messa a disposizione dal server. La rete Internet e le applicazioni che vengono utilizzate da chi si collega alla rete sono basate sull’architettura C/S. Dalla parte del client c’è il browser (IE o NETSCAPE NAVIGATOR) che richiede le pagine Web, dall’altra c’è un programma chiamato server Web (APACHE o IIS) che ha il compito di rispondere alle richieste ricevute (è sempre in funzione). La comunicazione tra queste due entità si basa sull’utilizzo di un protocollo chiamato HTTP (Hyper Text Transfer Protocol). Questo protocollo stabilisce come devono essere formulate le richieste da parte del client e le risposte da parte del server. XML e Tecnologia Servlet 35 Le principali richieste che possono essere fatte da un browser sono: Richiesta di una pagina Web, indicata con il comando GET; Richiesta di una pagina Web con la possibilità di spedire i dati al server, indicata con il comando POST. L’EVOLUZIONE DEL SERVER WEB Il contenuto dei documenti WWW ha subito un’evoluzione nel corso degli anni, si è passati dai contenuti statici a quelli dinamici. I contenuti dinamici lato client sono rappresentati dai linguaggi di scripting (come JavaScript e VBScript) e dalle Applet mentre quelli lato server si sono sviluppati come estensioni del server Web, come le pagine ASP (active server page) o quelle JSP (java server page), oppure mandando in esecuzione i programmi esterni che generano le pagine da inviare al browser in modo dinamico. Tutti questi programmi sono identificati dalla sigla CGI (common gateway interface), risiedono sul server e sono attivati quando viene ricevuta una richiesta da parte di un client. Un’evoluzione dei programmi CGI è rappresentata dalla SERVLET. TECNOLOGIA SERVLET Una SERVLET è un programma scritto in Java il cui scopo è quello di estendere le funzionalità del server Web. Ogni volta che il server Web riceve una richiesta che fa riferimento ad una servlet, invoca l’esecuzione di un metodo particolare ( i corrispondenti del metodo GET o POST) della servlet stessa con lo scopo di soddisfare la richiesta. Le servlet sono però più efficienti rispetto ai programmi CGI in quando richiedono l’esecuzione di un solo metodo e non di un programma intero ed inoltre ereditano tutti i vantaggi del linguaggio Java come la metodologia orientata agli oggetti, la portabilità del codice e le numerose librerie. COME FUNZIONANO LE SERVLET Tutto ciò che riguarda le servlet è racchiuso nelle due API javax.servlet e javax.servlet.http che non fanno parte delle librerie standard di Java ma sono rese disponibili solo con la versione Enterprise della Java Virtual Machine, la J2EE (bisogna includere a mano il file j2ee.jar). Per potere creare una servlet si deve specificare l’uso dei due package relativi alle servlet usando i comandi: import javax.servlet.*; import javax.servlet.http; La servlet in sé è rappresentata in pratica da una classe che viene definita estendendo la classe HttpServlet: public class <nome della classe> extends HttpServlet Tale classe contiene vari metodi che vengono ereditati e possono o meno essere ridefiniti e sono i metodi init, doGet, doPost e destroy. Una servlet è sempre invocata da una richiesta di un browser ma è comunque il server Web che si occupa di caricarla ed inizializzarla. Nella fase di inizializzazione viene chiamato il metodo init ed in seguito, solitamente ma non sempre, viene invocato il metodo service che ha il compito di capire il tipo di richiesta (GET o XML e Tecnologia Servlet 36 POST) ed indirizzarla ai metodi opportuni (doGet oppure doPost) che generano una risposta solitamente sotto forma di pagina Web e la spediscono al client; la servlet infine può essere eliminata dal metodo destroy. Le richieste e le risposte sono gestite rispettivamente dalle classi HttpServletRequest e HttpServletResponse. Gli oggetti generati dalla prima classe contengono le informazioni relative alla richiesta ricevuta dal client (variabili d’ambiente, parametri, tipo di richiesta ecc.) mentre quelli generati dalla seconda consentono di controllare la risposta da restituire al client. Sia la struttura del metodo doGet che del metodo doPost possiedono come parametri un oggetto relativo alla risposta e una relativo alla richiesta: public void doGet(HttpServletRequest richiesta,HttpServletResponse risposta) throws IOException,ServletException { ....... } Il costrutto throws serve per indicare quali sono le eccezioni che il metodo potrebbe generare; per impostare la risposta da restituire al client si deve specificare il tipo con l’istruzione Risposta.setContentType(“text/html”); Tramite un oggetto di classe PrintWriter poi è possibile aprire un canale per inserire tutti i dati testuali che vengono restituiti al client in risposta alla sua richiesta: PrintWriter out = risposta.getWriter(); out.println(“<HTML><BODY></BODY></HTML>”); out.close; Nel precedente esempio viene aperto il canale di output tramite la variabile out, generata una pagina HTML vuota e poi richiuso il canale. Una volta creata una servlet bisogna però avere un ambiente di sviluppo adatto per poterla eseguire ovvero bisogna disporre di un server Web. Nei prossimi esempi si farà riferimento al Server Web reso disponibile dalla Sun dal nome JSWDK (JavaServer Web Development Kit) che implementa le API relative alle servlet e a JSP. Per l’esecuzione della servlet bisogna seguire passo passo i seguenti punti: Installare sul disco C: il kit del JSWDK (se il file è zip bisogna solo estrarlo); Appena entrati nella cartella c:\jswdk-1.0\ eseguire il file startserver.bat; Compilare il file la servlet Java in questione (con la J2EE) creando il file eseguibile ( .class); Copiare il file eseguibile nella cartella c:\jswdk-1.0\examples\Webinf\servlets\ A questo punto non rimane che creare una pagina HTML responsabile di chiamare la servlet nel modo seguente: <html> <body> <a href = “http://localhost:8080/examples/servlets/ <nome della servlet>” > Collegamento alla servlet </a> XML e Tecnologia Servlet 37 </body> </html> Così cliccando sulla frase “Collegamento alla servlet” viene invocata l’esecuzione della servlet il cui indirizzo Web è http://localhost:8080/examples/servlets/ <nome della servlet> dove per <nome della servlet> è inteso il nome del file eseguibile senza l’estensione. QUERY SU XML CON XSL E SERVLET IL NOSTRO OBBIETTIVO Lo scopo di questa sezione è quello di spiegare come abbiamo realizzato una Servlet Java che, grazie all’aiuto di XSL, effettua query su un documento XML. Prima però di mostrare come abbiamo fatto, cercheremo brevemente di definire ciò che effettivamente rappresenta il nostro obbiettivo. Partendo da un documento XML contenente il database dell’orario scolastico della nostra scuola, è possibile decidere il tipo di interrogazione o query che si intende fare. Il file XML sarà visualizzato dal web browser Internet Explorer 5.5 a seconda della formattazione impostagli dal file XSL al quale fa riferimento; in questa pagina sarà possibile scegliere l’interrogazione (sui professori o sulle classi o sulle aule) e poi alla pressione del bottone “VISUALIZZA” verrà chiamata la Servlet vera e propria che, genererà come output una pagina html contenente il link al risultato dell’interrogazione scelta. PERCHÉ USARE UNA SERVLET JAVA Occorre specificare che usando esclusivamente XSL non sarebbe stato possibile realizzare qualcosa del genere, in quanto, anche con questo linguaggio è possibile definire dei criteri di selezione per gli elementi e quindi di formulare query, tali criteri devono essere specificati all’interno del file stesso e non vi è quindi la possibilità di influenzare dall’esterno il criterio di selezione. Per esempio con il seguente frammento di codice <xsl:for-each select = “OrarioScolastico/Orario [ MATRICOLA = ‘00172’ ]”> Il parser XSL avrebbe selezionato solo l’orario la cui matricola è ‘00172’. Come si può notare, il numero di matricola deve essere specificato all’interno del file stesso; quello che noi andremmo a fare è invece qualcosa del tipo <xsl:for-each select = “OrarioScolastico/Orario [ MATRICOLA = X ] “> Dove X è un valore generico che sarà introdotto successivamente dall’utente. Attualmente XSL non prevede dei parametri in input, ciò che rimane da fare è quindi creare un’applicazione che, una volta noto il valore di X, generi automaticamente il file XSL all’interno del quale X sarà sostituito proprio da un valore reale. È proprio in virtù di queste considerazioni che nasce la necessità di una Servlet Java ovvero di un’applicazione dinamica residente su un server Web. L’architettura del nostro progetto è quindi stabilita: il client sarà costituito dal file XML citato in precedenza ed avrà la possibilità con la pressione del bottone “VISUALIZZA” di invocare la Servlet che riceverà come XML e Tecnologia Servlet 38 parametri di input inseriti dall’utente il tipo e il valore dell’interrogazione da effettuare. La Servlet genererà poi il file XSL in modo che selezioni solo i campi opportuni dal documento XML. DUE DIFFERENTI FILOSOFIE Per la risoluzione del nostro problema le filosofie da adottare potrebbero essere due: quella di utilizzare un documento XML statico (ovvero che non viene mai modificato dalla Servlet) e quella di utilizzare un documento XML dinamico che ogni volta viene modificato dalla Servlet in modo tale da fare riferimento ad un file XSL diverso. Noi tra le due, abbiamo deciso di utilizzare un documento XML dinamico in quanto consente di gestire la multiutenza. Infatti, se con il primo approccio potevano sorgere problemi di concorrenza nel tentativo di creare ogni volta lo stesso file XSL, con l’utilizzo della seconda soluzione è permesso far reagire il documento XML dinamicamente a seconda del file XSL creato. LA SELEZIONE DELL’INTERROGAZIONE In questa sezione verrà spiegato come viene selezionato il tipo di interrogazione da eseguire e come vengono impostati i suoi parametri. Il file di partenza è il documento “ OrarioScolastico.xml ” che contiene il database dell’orario scolastico della nostra scuola e qui di seguito ne è riportato un frammento: <!--OrarioScolastico.xml--> <?xml version="1.0"?> <?xml-stylesheet type='text/xsl' href='OrarioScolastico.xsl'?> <OrarioScolastico> <Aule><IDAULA>1</IDAULA> …… <Classi><Classe>1A</Classe><Nome>1A</Nome><Specializzazione>PROVVISORIO</Speci alizzazione><Gruppo>GL_STD_PR1A</Gruppo></Classi> …… <Orario><MATRICOLA>00222</MATRICOLA><CLASSE>1D18</CLASSE><ORA>LU1</ORA></Orari o> …… <Personale><Matricola>00001</Matricola><Cognome>NUCCI</Cognome><Nome>NICOLA</N ome><InServizio>N</InServizio><DocAta>D</DocAta><Gruppo>GL_SEG_DR</Gruppo></Pe rsonale> …… </OrarioScolastico> Il file precedente è così strutturato: ha un elemento radice “OrarioScolastico” e 4 sottoelementi che sono “Personale”, ”Classi”, “Orario”, “Aule”; questi a loro volta hanno dei sottoelementi ognuno con il proprio valore. Come si può notare dalla terza riga, il documento fa riferimento per la sua visualizzazione web al foglio di stile “OrarioScolastico.xsl” che genererà in output 2 combobox nelle quali saranno racchiusi rispettivamente le informazioni sul personale e sulle classi. È fondamentale capire come sia, a tutti gli effetti, il file xsl a formattare i dati contenuti nel file xml e ha rendere possibile il seguente output. Qui di seguito è visualizzato il file “OrarioScolastico.xml” aperto con il browser Internet Explorer. XML e Tecnologia Servlet 39 Qui di seguito e invece riportata una porzione del file “OrarioScolastico.xl” <!--OrarioScolastico.xsl--> <?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <html> <head> <title> SCEGLI L'INTERROGAZIONE </title> </head> <body> <FORM name="FORM1" METHOD="GET" action="http://localhost:8080/examples/servlet/XSLQuery"> <b><txt> COSA VUOI CERCARE ? </txt></b> <!—-Inizio Professori--> <input type="radio" name="scelta" value="Personale"></input> Professori: <select name="p" onchange="ottienivalore()"> XML e Tecnologia Servlet 40 <script language="JavaScript"> function ottienivalore() { var matricola; matricola=document.FORM1.p.options[FORM1.p.selectedIndex].text; document.FORM1.ValorePersonale.value=matricola; } </script> <xsl:for-each select="OrarioScolastico/Personale [ InServizio = 'S' and DocAta='D' ]"> <option value="1"><xsl:value-of select="Nome"/>_<xsl:value-of select="Cognome"/> (<xsl:value-of select="Matricola"/>) </option> </xsl:for-each> </select> <!--FINE professori--> Prima di proseguire occorre sprecare alcune parole per spiegare come funziona il tutto. Il file è composto da un form il cui metodo è GET (restituisce i valori sulla barra degli indirizzi) e che come azione (al click del bottone “VISUALIZZA”) lancia la Servlet “XSLQuery.class” (da notare che però deve essere omessa l’estensione del file eseguibile) come si può vedere qui di seguito: <FORM name="FORM" METHOD="GET" action="http://localhost:8080/examples/servlet/XSLQuery"> L’indirizzo della nostra Servlet è “http://localhost:8080/examples/servlet/XSLQuery” dove “localhost:8080” rappresenta la root directory del nostro server web. In teoria quindi la servlet può essere eseguita da chiunque, in qualsiasi posto si trovi, basta cambiare l’indirizzo del server. Ecco come vengono inseriti nella combobox i valori opportuni: <option value="1"><xsl:value-of select="Nome"/><xsl:value-of select="Cognome"/></option> Nel caso del “Personale” però non dobbiamo inserire tutti i valori ma solo quelli che sono inseriti anche in “Orario” e che quindi tengono delle ore di lezione (ovvero tutti coloro che sono docenti e che sono in attività). Questo è stato reso possibile grazie all’interrogazione della seguente riga di comando xsl: <xsl:for-each select="OrarioScolastico/Personale [ InServizio = 'S' and DocAta='D' ]"> Inoltre all’evento “onChange()” di ogni combobox viene chiamata la funzione JavaScript “ottienivalore” che preleva il testo selezionato e lo salva in un campo di testo invisibile; questo è un piccolo stratagemma che abbiamo dovuto adottare per far si che la servlet ricevesse in input il valore selezionato vero e proprio, e non l’attributo “value” della combobox che è sempre uguale a uno. Nel riportare il codice del file xsl sono state omesse naturalmente le parti riguardanti le classi che sarebbero state quasi uguali a quelle dei professori. XML e Tecnologia Servlet 41 Riportiamo invece la dichiarazione di uno dei campi di testo invisibili e del bottone “VISUALIZZA”: <input type="hidden" name="ValorePersonale" size="10" value="00003"></input> <input type ="Submit" name="cerca" value="VISUALIZZA"/> Come ultimo bisogna ricordare che nel form sono presenti anche due radiobutton (“scelta”) che specificano il tipo di interrogazione ( se sul “Personale” o sulle “Classi”). LA SERVLET IN FUNZIONE A questo punto abbiamo spiegato come funziona la selezione dell’interrogazione da eseguire e quindi non rimane che spiegare cosa fa e come funziona la servlet. Come abbiamo già detto la servlet riceve come parametri di ingresso il tipo (radiobutton) e il valore dell’interrogazione (textbox nascosta) che vengono passati sulla barra degli indirizzi: Il compito della servlet prima di tutto è quello di ricevere e riuscire ad interpretare i parametri ricevuti in ingresso e il metodo che svolge questo compito è il metodo “doGet”: public void doGet(HttpServletRequest req,HttpServletResponse res) throws ServletException,IOException { res.setContentType("text/html"); String opzioneselezionata=req.getParameter("scelta"); ……… Una volta ricevuti i parametri (e adattandoli ad esempio per la matricola con il metodo “EstraiId” che però non verrà riportato) il compito della servlet sarà quello di generare un nuovo file xsl a partire dal file template “OrarioScolastico2.xsl.tmp” riportato in seguito <?xml version='1.0'?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match='/'> <html> <head><title>RISULTATO DELLA RICERCA</title></head> <body> <TABLE BGCOLOR="66CCFF" border="2"> <CAPTION ALIGN="left" STYLE="background-color: SCOLASTICO</B></CAPTION> <TBODY> <TR> <TH><B>@</B></TH> <TH><B>^</B></TH> <TH><B>§</B></TH> blue; color:white;"><B>ORARIO </TR> <tr><td rowspan="1000"><b><xsl:for-each select='OrarioScolastico/@ [ £ = "$" ]'> <xsl:value-of select='ç'/> XML e Tecnologia Servlet 42 <br/> </xsl:for-each></b></td></tr> <xsl:for-each select='OrarioScolastico/Orario [ £ = "$" ] ' <tr> > <td><xsl:value-of select='^'/></td> <td><xsl:value-of select='§'/></td> </tr> </xsl:for-each> </TBODY> </TABLE> <form name="form1" action="OrarioScolastico.xml"> <input type="submit" value=" OK "> </input> </form> </body> </html> </xsl:template> </xsl:stylesheet> È chiaro che la servlet dovrà andare a sostituire tutti i caratteri come per esempio @ § £ $ ecc… con i valori adatti come per esempio MATRICOLA, Personale ecc…. La funzione di sostituzione sarà svolta dal seguente metodo: private String makeXSL(......) throws Exception { RandomAccessFile source=new RandomAccessFile("C:\\jswdk-1.0\\examples\\WEBINF\\servlets\\OrarioScolastico2.xsl.tmp","r"); byte v[]=new byte[(int)source.length()]; source.readFully(v); Data=new String(v); Data=sostituisci(specifica,'@'); Data=sostituisci(specifica,'@'); Data=sostituisci(condizione1,'£'); Data=sostituisci(condizione,'£'); Data=sostituisci(condizione2,'ç'); Data=sostituisci(valore,'$'); Data=sostituisci(valore,'$'); Data=sostituisci(campo_da_selezionare1,'^'); Data=sostituisci(campo_da_selezionare1,'^'); Data=sostituisci(campo_da_selezionare2,'§'); Data=sostituisci(campo_da_selezionare2,'§'); String nomefile= "OrarioScolastico" + System.currentTimeMillis() + ".xsl"; RandomAccessFile target=new RandomAccessFile("C:\\jswdk-1.0\\examples\\WEBINF\\servlets\\"+nomefile,"rw"); target.writeBytes(Data); source.close(); target.close(); return nomefile; } Ecco in poche parole cosa fa il metodo: prima apre il file “OrarioScolastico.xsl.tmp” e memorizza il suo contenuto nella variabile “xslData”, poi chiama un certo numero di volte la funzione “sostituisci” che riceve come parametri la stringa da inserire e il carattere da sostituire: private String sostituisci(String parola,char carattere) { char ch='\0'; int i=0; for (;ch!=carattere;i++) ch=Data.charAt(i); String PrimaParte=Data.substring(0,i-1); return PrimaParte+parola+Data.substring(i,Data.length()); } XML e Tecnologia Servlet 43 Infine viene creato un nuovo file xsl nel quale viene messo tutto il contenuto modificato del file precedente (OrarioScolastico2.xsl.tmp). In questo modo il file che esegue l’interrogazione è completo; va però precisato che il file creato non è sempre lo stesso ad ogni nuovo accesso in modo da consentire la multiutenza. Il nome del file sarà sempre: “OrarioScolastico” + numero di millisecondi passati dal 1^ gennaio 1970 + “.xsl” A questo punto non rimane che modificare (con il metodo “modificaXML”) il secondo database dei professori “OrarioScolastico2.xml.tmp” e generarne un altro “OrarioScolastico2.xml” sostituendo $ nel primo con il nome del file xsl di riferimento appena creato. I RISULTATI DELL’INTERROGAZIONE Ora che la servlet ha svolto il suo compito non deve fare altro che generare un output PrintWriter out =res.getWriter(); out.println("<html><head><title>VISUALIZZA IL RISULTATO DELLA TUA RICERCA </title></head>"); out.println("<body><a href='C:\\jswdk-1.0\\examples\\WEBINF\\servlets\\OrarioScolastico2.xml'> "); out.println("<center><b>VISUALIZZA IL RISULTATO DELLA TUA INTERROGAZIONE</b></center> </a></body></html>"); out.close(); il cui risultato sul browser è il seguente Il link della pagina precedente porta naturalmente al file “OrarioScolastico2.xml” che la servlet ha appena creato e che fa riferimento al foglio di stile “OrarioScolastico … .xsl” frutto anch’esso del lavoro della servlet. XML e Tecnologia Servlet 44 Ecco il risultato finale dell’interrogazione Per concludere se all’inizio fosse stato selezionato il professor Andrea Dotti il risultato sarebbe stato il precedente ovvero tutte le ore e le classi settimanali del tal professore. Premendo il bottone ok è possibile tornare alla schermata iniziale. Tutta la procedura sopra descritta può essere schematizzata con il seguente schema XML e Tecnologia Servlet 45 Come si può vedere aprendo il file xml (che fa riferimento a quello xsl) viene generata una pagina web dove si possono decidere i parametri della query; questa pagina a sua volta chiama la servlet che crea i due file (xsl e xsl) che a loro volta generano una pagina web con il risultato dell’interrogazione. BIBLIOGRAFIA Rivista mensile “IoProgrammo” numeri 47 – 48 – 49 – 50 – 72. "Il linguaggio Java" di A. Lorenzi e A. Rizzi ed. ATLAS SITOGRAFIA www.w3.org: il consorzio che controlla lo sviluppo dell’XML www.google.it: ore e ore di ricerca nel web www.html.it: guide sull’XML, XSL e DTD www.mokabyte.it: Java e XML www.jdom.org: sito dei realizzatori e distributori di jdom www.altova.com: distributore di XMLSPY, il miglior editor XML in circolazione www.xmlspy.com: sito di XMLSPY java.sun.com: sito degli sviluppatori di java www.perfectxml.com: aiuto su SQL SERVER e XML www.itis.pr.it/progetti/xml: tesina anno 2002/2003 di Zatti e Petrazzoli XML e Tecnologia Servlet 46