- Serializzazione e deserializzazione XML di oggetti -
|
|||
COSA SERVE PER QUESTO TUTORIAL | |||
Download | Chiedi sul FORUM | Glossario | conoscenze basiche di VB .Net | ||
Serializzazione XML di una classe contenente la configurazione del programma | |||
INTRODUZIONE ALLA SERIALIZZAZIONE XML Cosa significa a cosa serve serializzare oggetti tramite XML.
In molte occasioni può sorgere la necessità di serializzare (su disco o
su un qualsiasi altro flusso, ad esempio di rete) il contenuto di un
oggetto cosicché possa essere caricato in seguito, magari da un altro
software scritto in un altro linguaggio su un'altra piattaforma. Per fare questo esiste la possibilità di servirsi delle classi
per la serializzazione binaria offerte dal framework .Net (in
particolare System.Runtime.Serialization.Formatters.Binary.BinaryFormatter) ma se è
necessario che i dati siano consultabili da piattaforme diverse (ad
esempio da un'applicazione in Java, JavaScript o qualunque altro
linguaggio) o anche da un essere umano, ancora una volta, la scelta
migliore è certamente servirsi di XML, formato elegante, standard ed
estremamente portabile. La classe chiave per la serializzazione/de-serializzazione
in XML è XmlSerializer in System.Xml.Serialization: grazie ai metodi
Serialize e Deserialize in poche righe di codice è possibile creare un
documento XML che rappresenta i campi pubblici (proprietà e membri) di
un certo oggetto. Serializzare la configurazione di un programma su disco personalizzando l'output XML. Immaginiamo di dover serializzare una classe di configurazione di un client FTP definita come segue: Public Class Configuration Private strHost As String Private intPort As Integer 'Le proprietà pubbliche sono oggetto della serializzazione Public Property Host() As String Get Return strHost End Get Set(ByVal value As String) strHost = value End Set End Property Public Property Port() As Integer Get Return intPort End Get Set(ByVal value As Integer) intPort = value End Set End Property End Class Come si può vedere essa è composta da due campi privati e due proprietà pubbliche, una stringa e un numero intero. Vediamo come potrebbe essere scritta la routine da usare per salvare le informazioni che un'istanza della classe Configuration contiene: Sub Save(ByVal strFile As String, ByVal cfg As Configuration) Dim wrtFile As New IO.FileStream(strFile, IO.FileMode.Create) Dim xsrSerializer As New XmlSerializer(GetType(Configuration)) xsrSerializer.Serialize(wrtFile, cfg) wrtFile.Close() End Sub Il codice è estremamente semplice: dati un percorso di file e l'istanza della classe Configuration da serializzare su disco si crea un FileStream per scrivere su disco, si crea un oggetto di tipo XmlSerializer (situato nel namespace System.Xml.Serialization) passando al costruttore il tipo dell'oggetto che si desidera serializzare, in questo caso Configuration, a questo punto si chiama il metodo Serialize con parametri lo stream e l'istanza della classe in questione e infine si chiude lo stream aperto. Vediamo un possibile risultato prodotto da questo codice: <?xml version="1.0"?> <Configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <Host>ftp.test.com</Host> <Port>21</Port> </Configuration> Il codice XML dovrebbe essere abbastanza autoesplicativo, ma in
sintesi è stato creato un elemento radice chiamato "Configuration" (come
la classe stessa) dotato di alcuni attributi con riferimenti agli
standard XSI e XSD (non importa ora capire di cosa si tratti) e due
sottoelementi "Host" e "Port" che contengono a loro volta le informazioni
dell'oggetto serializzato. <XmlRoot("configurazione")> _ Public Class Configuration [...] End Class Per personalizzare il nome di un elemento figlio, ad esempio cambiare da "Host" a "Server" il nome dell'elemento corrispondente alla proprietà Host si deve usare l'attributo XmlElement: <XmlElement("Server")> _ Public Property Host() As String [...] End Property Se invece si desidera ignorare una proprietà perché non adatta a essere serializzata o comunque inutile ci si deve servire dell'attributo XmlIgnore. Ad esempio pensiamo di aggiungere la proprietà Uri, che restituisce un Uri per accedere al server FTP. Poiché System.Uri non è dotato di un costruttore privo di parametri va escluso dalla serializzazione: <XmlIgnore()> _ Public ReadOnly Property Uri() As Uri Get Return New Uri(String.Format("ftp://{0}:{1}{2}/", Me.Host, Me.Port)) End Get End Property Infine vediamo come vengono trattati gli elementi non primitivi (quindi qualcosa di più articolato di una semplice stringa o un numero intero). Creiamo la classe UserPass contenente una coppia di stringhe per nome utente e password e associamola ad una proprietà della classe Configuration tramite una lista, cosicché sia possibile per avere diverse credenziali (coppia di nome utente e password) per accedere al nostro ipotetico server FTP. Publi Class Configuration Private uspUsers As New List(Of UserPass) [...] Public ReadOnly Property Users() As List(Of UserPass) Get Return uspUsers End Get End Property [...] End Class Vediamo la classe UserPass: Public Class UserPass Private strUser As String Private strPass As String Public Sub New() End Sub <XmlAttribute("username")> _ Public Property User() As String [...] End Property <XmlAttribute("password")> _ Public Property Pass() As String [...] End Property End Class Come si nota la classe è dotata di un costruttore senza parametri e due proprietà pubbliche per nome utente e password con attributo XmlAttribute. Quest'ultimo indica che le due proprietà dovranno essere serializzate come attributi XML dell'elemento padre (in questo caso UserPass) rispettivamente chiamati "username" e "password". Ecco un possibile output XML: <?xml version="1.0"?> <configurazione xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <Server>ftp.test.com</Server> <Port>21</Port> <Users> <UserPass username="anonymous" password="email@address.com" /> <UserPass username="Carl" password="carlitos" /> </Users> </configurazione>DESERIALIZZARE UN FILE XML Come caricare dal disco un file XML rappresentante un oggetto serializzato in precedenza. Ovviamente la serializzazione XML non avrebbe alcuna utilità senza la possibilità di de-serializzare, ecco dunque una ruotine per de-serializzare la classe Configuration da un file XML: Function LoadFromFile(ByVal strFile As String) As Configuration Dim rdr As New IO.FileStream(strFile, IO.FileMode.Open) Dim xsrDeserializer As New XmlSerializer(GetType(Configuration)) Dim cfgResult As Configuration = _ CType(xsrDeserializer.Deserialize(rdr), Configuration) rdr.Close() Return cfgResult End Function Il procedimento è simile alla serializzazione se non per il fatto che il file viene aperto in modalità Open e si chiama il metodo Deserialize, passando solamente lo stream.
|
|||
<< INDIETRO | by VeNoM00 |