| < Precedente | Manipolazione di file XML | Successivo > |
XML è un acronimo per eXtensibale Markup Language (Linguaggio di Contrassegno Estensibile). Si tratta di un linguaggio per mezzo del quale è possibile immagazzinare dati in una struttura fortemente gerarchica e organizzata, un modello ideale che rispecchia appieno il meccanismo della programmazione orientata agli oggetti. L'XML è oggi usatissimo in un gran numero di casi, e la sua grande diffusione si deve attribuire alla sua flessibilità. Non so se "i miei venticinque lettori" conoscano l'HTML, ma è probabile di sì. Nell'HTML ci sono tag e proprietà definiti: il web master può usare solamente quelli. Al contrario, in XML è il programmatore che definisce i tag e gli attributi, ossia la grammatica con cui il documento viene scritto.
Prima di iniziare, segue una breve introduzione all'XML.
Introduzione all'XML
Un documento XML è un file di testo contenente dati incasellati in una struttura gerarchico-logica fortemente definita. Ogni parte di
questa struttura viene detta elemento (o nodo in analogia con la formazione "ad albero" già descritta con il controllo
TreeView). Ogni elemento può possedere informazioni ulteriori che ne specificano le proprietà peculiari: tali informazioni sono
specificate sotto forma di attributi. L'elemento principale, di ordine superiore a tutti gli altri, si chiama elemento root
o semplicemente root. L'unica entità in grado di stare allo stesso livello del root è la dichiarazione della versione
xml o altre direttive di interpretazione. Ecco un esempio di semplice file:
<?xml version="1.0" ?>
<biblioteca>
<libro titolo="I sei numeri dell'universo" autore="Martin Rees">
<capitolo titolo="Il cosmo e il microcosmo" numero="1" pagina="11">
Alla base della struttura del nostro universo - non solo ...
</capitolo>
</libro>
<libro titolo="Le ostinazioni di un matematico" autore="Didier Nordon">
<capitolo titolo="Dalle stalle alle stelle" numero="1" pagina="11">
Ecco a voi un romanzo il cui protagonista conosce una morte ...
</capitolo>
</libro>
</biblioteca>
Questo codice sintetizza i primi due libri che mi sono capitati in mano: ne specifica alcuni dettagli e riporta un pezzo della prima frase
del primo capitolo. Partendo da questo sorgente, biblioteca, libro e capitolo sono elementi, mentre titolo, autore, numero e pagina sono attributi di
questi elementi. Biblioteca è il root. Dopo aver letto e individuato le varie parti del documento, bisogna fare alcune osservazioni:
- Tutti i valori, qualsiasi sia il loro tipo, vanno racchiusi tra apici singoli o doppi
- Ogni elemento aperto deve essere chiuso. Se un elemento non ha contenuto si può usare la sintassi abbreviata
<elemento attributo="valore" ... />
- Tutto il testo è analizzato dai parser in modalità case-sensitive
- Ogni identificatore di elemento o attributo deve essere un nome valido. Per questo verso segue le stesse regole per la creazione di un nome di variabile VB, ad eccezione della possibilità di usare il trattino
Uso di XML in ambiente .NET
Descrivere dettagliatamente tutte le classi atte alla manipolazione dei documenti XML sarebbe un enorme spreco di tempo, e sicuramente non
aiuterebbe poi molto: inoltre una documentazione esauriente e dettagliata esiste già all'interno della libreria MSDN di Microsoft.
In questo paragrafo elencherò brevemente tali classi con una piccola descrizione:
- System.Xml.XmlAttribute : rappresenta un attributo
- System.Xml.XmlCDataSection : rappresenta una sezione CData. Questo tipo di elemento è un contenitore di testo esteso, al cui interno si possono dichiarare anche pezzi di codice XML: in questo modo essi non si confondono con il resto del documento
- System.Xml.XmlComment : rappresenta un commento
- System.Xml.XmlDocument : rappresenta un intero documento XML ed espone metodi per il salvataggio e il caricamento veloce
- System.Xml.XmlElement : rappresenta un singolo elemento
- System.Xml.XmlNode : rapprsenta un nodo. Da questa classe derivano molte altre
- System.Xml.XmlReader : classe astratta di base per XmlTextReader e XmlValidatigReader, che consentono rispettivamente la lettura di testo xml o di uno schema xml
- System.Xml.XmlWriter : classe astratta di base per XmlTextWriter, che consente la scrittura di testo xml sul documento
Iniziamo con XmlTextRaeder. Questa classe espone una quantità gigantesca di membri, che sarebbe troppo dispendioso elencare completamente. Il suo funzionamento non è semplicissimo da capire a un primo impatto, ma un poco di ragionamento lo renderà più chiaro. La funzione principale è Read, che legge un nodo e restituisce False se non c'è niente da leggere. Una volta letto, le sue informazioni diventano disponibili attraverso le proprietà di XmlTextReader, che funge da totum continens: infatti gli attributi e i contenuti vengono letti tutti nello stesso modo, considerati, quindi, tutti nodi. Ecco un esempio che prende un file XML, lo analizza e lo restituisce sotto forma di file INI (anche se questo non supporta la gerarchia):
Imports System.Xml
Module Module1
Sub Main()
'Crea un nuovo lettore xml.
Dim Reader As New Xml.XmlTextReader("C:libri.xml")
Dim Indent, Content As String
'La funzione Reader.Read legge il nodo successivo e
'restituisce False se non c'è niente altro da
'leggere. Il ciclo legge tutti gli elementi
Do While Reader.Read
'Indenta il codice a seconda della profondità
'del nodo
Indent = New String(" ", Reader.Depth * 2)
'Se il nodo è un tag di chiusura, come ad
'esempio </libro>, lo salta
If Not Reader.IsStartElement Then
'Viene considerato un nodo anche il testo all'interno
'di un elemento, perciò bisogna controllare
'se questo non sia effettivamente un testo
If Reader.HasValue Then
Console.WriteLine(Reader.Value)
End If
Continue Do
End If
'Scrive il nome del tag a schermo, tra parentesi quadre,
'come nei file INI
Console.WriteLine("{0}[{1}]", Indent, Reader.Name)
'Se l'elemento ha un contenuto, lo memorizza per scriverlo
'successivamente a schermo
If Reader.HasValue AndAlso Reader.Value <> vbCrLf Then
Content = Reader.Value
Else
Content = Nothing
End If
'Se l'elemento possiede attributi, li scrive
If Reader.HasAttributes Then
For I As Int16 = 0 To Reader.AttributeCount - 1
Reader.MoveToAttribute(I)
Console.WriteLine("{0}{1} = {2}", Indent, _
Reader.Name, Reader.Value)
Next
End If
If Content IsNot Nothing Then
Console.WriteLine("{0}Contenuto = {1}", Indent, Content)
End If
Loop
Reader.Close()
Console.ReadKey()
End Sub
End Module
Il risultato sarà questo:
[biblioteca]
[libro]
titolo = I sei numeri dell'universo
autore = Martin Rees
[capitolo]
titolo = Il cosmo e il microcosmo
numero = 1
pagina = 11
Alla base della struttura del nostro universo - non solo ...
[libro]
titolo = Le ostinazioni di un matematico
autore = Didier Nordon
[capitolo]
titolo = Dalle stalle alle stelle
numero = 1
pagina = 11
Ecco a voi un romanzo il cui protagonista conosce una morte ...
Passiamo ora a XmlTextWriter: i suoi membri sono molto meno numerosi ed usarlo è assai semplice. Quasi tutti i metodi iniziano per "Write" e servono a scrivere diversi tipi di dati, elementi, attributi e specifiche del documento. La cosa importante da ricordarsi quando si lavora con XmlTextWriter è di richiamare sempre, prima di ogni metodo, WriteStartDocument, che si occupa di inizializzare il documento correttamente con le direttive adatte; e dopo aver terminato le varie operazioni WriteEndDocument, che chiude tutto. Ecco un esempio:
Imports System.Text
Imports System.Xml
Module Module2
Sub Main()
'Il secondo parametro del costruttore è obbligatorio
'e specifica quale codifica di caratteri si debba usare.
'In questo caso ho messo UTF-8, in modo da poter usare anche
'i caratteri accentati
Dim Writer As New XmlTextWriter("C:guida.xml", UTF8Encoding.UTF8)
With Writer
.Indentation = 2
.IndentChar = " "
'Scrive l'intestazione
.WriteStartDocument()
'Scrive l'elemento root
.WriteStartElement("guida")
'E l'attributo "capitoli"
.WriteAttributeString("capitoli", "100")
'Scrive un elemento capitolo
.WriteStartElement("capitolo")
.WriteAttributeString("numero", "1")
.WriteAttributeString("titolo", "Introduzione")
.WriteString("A differenza del Visual Basic classico, ...")
.WriteEndElement()
'Chiude il root e il documento
.WriteEndElement()
.WriteEndDocument()
.Close()
End With
Console.ReadKey()
End Sub
End Module
