Serializzazione e lettura xml

lunedì 07 aprile 2008 - 13.23

Injegner Profilo | Newbie

Buongiorno a tutti,
vorrei sottoporvi un caso:
io devo leggere un XML (pre-formattato come output di sw commerciale) e aggiungere interi oggetti di diversi tipi. Mi sono ricreato gli oggetti con cui devo lavorare nel codice e stavo pensando alla possibilità di serializzare i nuovi oggetti da aggiungere. Il problema è che non so come fare a posizionare un nuovo gruppo di nodi serializzati in un xml già esistente... L'alternativa sarebbe usare il DOM, in modo da andare ad individuare l'oggetto a cui devo aggiungere sotto-oggetti e scriverceli dentro... ma mi sembra un po' macchinoso.. anche perchè comporta la creazione di una quantità di Element e Nodes un po' grande..
Sapete se c'è la possibilità di usare queste due vie insieme? serializzare un oggetto e dirgli di posizionarlo ad un certo livello in un xml esistente, senza ricrearsi tutta la struttura dell'xml di destinazione, che nel mio caso è enorme?
Scusate se ho chiesto una cosa assurda... ma magari non è così assurda..
grazie mille,
Paolo

freeteo Profilo | Guru

ciao,
quando lavoro con xml, e sono dentro a .net, faccio fare al framework la serializzazione/deserializzazione degli oggetti, e poi lavoro sempre con quelli.

Ti faccio un esempio, se voglio leggere/scrivere da un file xml (o anche da una stringa in memoria passando attraverso un MemoryStream) una lista di "Articoli", dentro al mio programma lavorero' con un'entita' "Articolo".
Nel caso di database, ogni colonna sara' mappata su una proprieta' di questo oggetto che il mio programma deve gestire, se invece parliamo di Xml, le stesse proprieta' saranno mappate come attributi su nodi Xml.

Ad esempio una classe articolo potrebbe avere:
class Articolo { private string nome = string.Empty; public string Nome { get { return nome; } set { nome = value; } } private List<Elemento> elementi; public List<Elemento> Elementi { get { return elementi; } set { elementi= value; } } ...



Poi se voglio avere piu' controllo sull'xml generato decoro le classi con gli attributi:
class Articolo { private string nome = string.Empty; [XmlAttribute("NAME")] public string Nome { get { return nome; } set { nome = value; } } private List<Elemento> elementi; [XmlArray("MIOTAG")] public List<Elemento> Elementi { get { return elementi; } set { elementi= value; } } ...


E quindi da codice lavoro sempre con gli oggetti che sono istanze/collection delle mie classi, e leggere e scrivere diventa abbastanza banale:
XmlSerializer serializer = new XmlSerializer(typeof(List<Articolo>)); //--- lettura List<Articolo> lista = new List<Articolo>(); using (FileStream stream = new FileStream("...", FileMode.Open)) { lista = serializer.Deserialize(stream) as List<Articolo>; } ... //--- scrittura using (FileStream stream = new FileStream("...", FileMode.Create)) { serializer.Serialize(stream, lista) ; }




Adesso non so se il tuo progetto (e quindi il tuo file xml) sia riconducibile a questo tipo di approccio, pero' a mio avviso, è il piu' efficiente soprattuto perche' tu lavori sempre sfruttando .net, come ade esempio i generics (List<T>) e quindi come dici giustamente tu, non devi farti "noiosamente" tuttal struttura di Nodi lavorando con Xml etc...

Poi se hai la fortuna di lavorare con framework 3.5 allora la cosa puo' cambiare visto che hai Linq

ciao.

Matteo Raumer
[MCAD .net]
http://blogs.dotnethell.it/freeteo

Injegner Profilo | Newbie

Ti ringrazio freeteo, mi hai dato una visione molto chiara... però il mio problema consiste nella lettura di un file di cui NON ho modellato in classi la struttura (mentre se lo deserializzo devo averne la descrizione in un Type del progetto..) e nell'aggiunta in tale file di oggetti di cui invece ho le classi corrispondenti e che quindi posso serializzare facilmente..
il problema consiste nel capire come posizionare nel file di partenza i miei oggetti (e quindi individuare il nodo in cui inserire i miei oggetti) perchè per quanto ne so se non ho la descrizione in classi di tutto il file non lo posso deserializzare in toto.. Se usassi il DOM potrei leggere nel file il nodo che ha determinate caratteristiche ed aggiungergli e.g. dei figli.. ma se uso il DOM per leggere, poi posso usare la serializzazione per scrivere?
Non so se è chiaro... Sono un po' approssimativo perchè non conosco tutti i termini corretti...
Grazie! Paolo

freeteo Profilo | Guru

>ma se uso il DOM per leggere, poi posso usare la serializzazione
>per scrivere?
eh purtroppo no, devi usare a questo punto tutto tramite XmlDocument, in questo modo:

XmlDocument docXml = new XmlDocument(); //--- lettura docXml.Load(...) //--- aggiungo un nodo ad un nodo esistente XmlNode newNodo = docXml.CreateNode(XmlNodeType.Element, "Elemento", null); newNodo.Attributes.Append(docXml.CreateAttribute("Nome")); newNodo.Attributes["Nome"].Value = layout.Nome; nodoEsistente.AppendChild(newNodo); ... //--- salvataggio docXml.Save(...)

dove "nodoEsistente" è un nodo che puoi recuperare tramite "GetElementById", o "GetElementsByTagName" oppure se hai bisogno di cose piu' complesse devi usare XPath:
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra


>Non so se è chiaro... Sono un po' approssimativo perchè non conosco
>tutti i termini corretti...
nessun problema, ti sei spiegato benissimo


>Grazie! Paolo
grazie a te, spero di esserti stato utile.
ciao.

Matteo Raumer
[MCAD .net]
http://blogs.dotnethell.it/freeteo

Injegner Profilo | Newbie

Grazie freeteo.. effettivamente era esattamente quello che stavo facendo.. mi fa piacere averne trovato conferma!
Grazie, ciao

freeteo Profilo | Guru

eh si, io preferisco passare per le classi di .net come mio "pattern", pero' ovvio che se non puoi, XmlDocument è cmq un ottimo oggetto...solo che devi scrivere 1po di codice...vabbeh poco male

ciao.

Matteo Raumer
[MCAD .net]
http://blogs.dotnethell.it/freeteo
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5