Language Integrated Query LINQ to XML A cura

  • Slides: 23
Download presentation
Language Integrated Query LINQ to XML A cura del docente Giuliano Pellegrini Parisi -

Language Integrated Query LINQ to XML A cura del docente Giuliano Pellegrini Parisi - © 2009

Il linguaggio LINQ Dalla versione del framework. NET 3. 5 è possibile sfruttare le

Il linguaggio LINQ Dalla versione del framework. NET 3. 5 è possibile sfruttare le potenzialità di un linguaggio integrato per la manipolazione delle informazioni che è LINQ ossia “Language Integrated Query”. La semantica di LINQ non è difficile e permette di lavorare in modo semplice ed immediato con qualsiasi tipo di informazione e sorgente dati. In questa lezione vedremo come LINQ permetta di effettuare la serializzazione e deserializzazione nel formato XML. http: //www. itiserale. it

Namespace necessari Per utilizzare “LINQ to XML” è necessario aggiungere al proprio progetto la

Namespace necessari Per utilizzare “LINQ to XML” è necessario aggiungere al proprio progetto la rispettiva libreria: using System. Xml. Linq; http: //www. itiserale. it

fbbl. Enti. Pubblici Per serializzare e deserializzare utilizzando “LINQ to XML”, la libreria “fbbl.

fbbl. Enti. Pubblici Per serializzare e deserializzare utilizzando “LINQ to XML”, la libreria “fbbl. Enti. Pubblici” non necessità di nessun tipo di autorizzazione e regole, quindi potete eliminare: • L’interfaccia ISerializable • [Serializable] • Il metodo Get. Object. Data per la serializzazione • Tutti i costruttori di classe per la deserializzazione • System. Runtime. Serialization http: //www. itiserale. it

I pilastri del mondo LINQ http: //www. itiserale. it

I pilastri del mondo LINQ http: //www. itiserale. it

Local Type Inference Nella lingua italiana il termine inferire significa “trarre una conclusione”, e

Local Type Inference Nella lingua italiana il termine inferire significa “trarre una conclusione”, e tale concetto è stato applicato anche a partire dal. NET 3. 5. Dichiariamo la seguente variabile: int valore = 18; Applico la tipizzazione ad intero var valore 2 = 24; Applico il local type inference E’ il compilatore di C# che inferisce (trae la conclusione) il tipo sulla variabile chiamata “valore 2”, quindi la renderà intera. Per chi conosce il linguaggio Visual Basic “var” non ha nulla a che vedere con la dichiarazione di variabili “variant”, ossia variabili di tipo “generico”, qui accade proprio il contrario lasciando al compilatore l’onere di stabilire il tipo. http: //www. itiserale. it

XML è un metalinguaggio utilizzando come standard mondiale per lo scambio di informazioni tra

XML è un metalinguaggio utilizzando come standard mondiale per lo scambio di informazioni tra sistemi eterogenei, ad esempio un macchina Microsoft Windows e un server Unix. http: //www. itiserale. it

Formato XML <? xml version="1. 0" encoding="utf-8"? > <Ambasciate> <Ambasciata> <Nome. Ente>Amb. d'Italia</Nome. Ente>

Formato XML <? xml version="1. 0" encoding="utf-8"? > <Ambasciate> <Ambasciata> <Nome. Ente>Amb. d'Italia</Nome. Ente> <Tipo. Ente>Ambasciata</Tipo. Ente> <Nazione>Russia</Nazione> <Presidiato>true</Presidiato> <Incorporato>true</Incorporato> <Capitale>Mosca</Capitale> <Nome>Andrej</Nome> <Cognome>Mashekno</Cognome> <Sesso>M</Sesso> <Eta>56</Eta> <Indirizzo>Puskin, 1</Indirizzo> <Citta>Mosca</Citta> <Tipo. Visto>Turistico</Tipo. Visto> <Durata. Visto>45 gg</Durata. Visto> <Numero. Uomini>Unità massime: 10</Numero. Uomini> </Ambasciata> <Nome. Ente>Amb. d'Italia</Nome. Ente> <Tipo. Ente>Ambasciata</Tipo. Ente> <Nazione>Cina</Nazione> <Presidiato>true</Presidiato> <Incorporato>true</Incorporato> <Capitale>Pechino</Capitale> <Nome>Lin Pan</Nome> <Cognome>Jong</Cognome> <Sesso>M</Sesso> <Eta>39</Eta> <Indirizzo>Pihon Kon, 1</Indirizzo> <Citta>Pechino</Citta> <Tipo. Visto>Turistico</Tipo. Visto> <Durata. Visto>45 gg</Durata. Visto> <Numero. Uomini>Unità massime: 10</Numero. Uomini> </Ambasciata> </Ambasciate> L’intestazione del file XML inizia e finisce sempre con: <? xml …………. ? > Questa riga indica la versione del linguaggio XML e l’utilizzo dell’ “Unicode Transformation Format” ad 8 bit. Unicode è uno standard che assegna un codice univoco ad ogni carattere della tastiera comprendendo anche tutti i caratteri che non appartengono al set dei simboli latini. Unicode è l’evoluzione del vecchio standard ASCII. http: //www. itiserale. it

Formato XML <? xml version="1. 0" encoding="utf-8"? > <Ambasciate> <Ambasciata> <Nome. Ente>Amb. d'Italia</Nome. Ente>

Formato XML <? xml version="1. 0" encoding="utf-8"? > <Ambasciate> <Ambasciata> <Nome. Ente>Amb. d'Italia</Nome. Ente> <Tipo. Ente>Ambasciata</Tipo. Ente> <Nazione>Russia</Nazione> <Presidiato>true</Presidiato> <Incorporato>true</Incorporato> <Capitale>Mosca</Capitale> <Nome>Andrej</Nome> <Cognome>Mashekno</Cognome> <Sesso>M</Sesso> <Eta>56</Eta> <Indirizzo>Puskin, 1</Indirizzo> <Citta>Mosca</Citta> <Tipo. Visto>Turistico</Tipo. Visto> <Durata. Visto>45 gg</Durata. Visto> <Numero. Uomini>Unità massime: 10</Numero. Uomini> </Ambasciata> <Nome. Ente>Amb. d'Italia</Nome. Ente> <Tipo. Ente>Ambasciata</Tipo. Ente> <Nazione>Cina</Nazione> <Presidiato>true</Presidiato> <Incorporato>true</Incorporato> <Capitale>Pechino</Capitale> <Nome>Lin Pan</Nome> <Cognome>Jong</Cognome> <Sesso>M</Sesso> <Eta>39</Eta> <Indirizzo>Pihon Kon, 1</Indirizzo> <Citta>Pechino</Citta> <Tipo. Visto>Turistico</Tipo. Visto> <Durata. Visto>45 gg</Durata. Visto> <Numero. Uomini>Unità massime: 10</Numero. Uomini> </Ambasciata> </Ambasciate> Con i simboli <…. . > si indica un nodo dell’albero XML, il quale deve sempre avere il rispettivo nodo di chiusura: <Ambasciate> … </Ambasciate> Il carattere “/” indica il nodo di chiusura. In questo file <Ambasciate> è il “root element” ossia il nodo XML che contiene a sua volta altri nodi, in un certo senso è il nodo padre o se preferite il contenitore principale dentro il quale possiamo mettere in cascata tutti i contenitori che mi servono. http: //www. itiserale. it

Formato XML 1° nodo XML Ambasciata 2° nodo XML Ambasciata <? xml version="1. 0"

Formato XML 1° nodo XML Ambasciata 2° nodo XML Ambasciata <? xml version="1. 0" encoding="utf-8"? > <Ambasciate> <Ambasciata> <Nome. Ente>Amb. d'Italia</Nome. Ente> <Tipo. Ente>Ambasciata</Tipo. Ente> <Nazione>Russia</Nazione> <Presidiato>true</Presidiato> <Incorporato>true</Incorporato> <Capitale>Mosca</Capitale> <Nome>Andrej</Nome> <Cognome>Mashekno</Cognome> <Sesso>M</Sesso> <Eta>56</Eta> <Indirizzo>Puskin, 1</Indirizzo> <Citta>Mosca</Citta> <Tipo. Visto>Turistico</Tipo. Visto> <Durata. Visto>45 gg</Durata. Visto> <Numero. Uomini>Unità massime: 10</Numero. Uomini> </Ambasciata> <Nome. Ente>Amb. d'Italia</Nome. Ente> <Tipo. Ente>Ambasciata</Tipo. Ente> <Nazione>Cina</Nazione> <Presidiato>true</Presidiato> <Incorporato>true</Incorporato> <Capitale>Pechino</Capitale> <Nome>Lin Pan</Nome> <Cognome>Jong</Cognome> <Sesso>M</Sesso> <Eta>39</Eta> <Indirizzo>Pihon Kon, 1</Indirizzo> <Citta>Pechino</Citta> <Tipo. Visto>Turistico</Tipo. Visto> <Durata. Visto>45 gg</Durata. Visto> <Numero. Uomini>Unità massime: 10</Numero. Uomini> </Ambasciata> </Ambasciate> All’interno del nodo root element, inserisco tutti i nodi <Ambasciata> che desidero indicando il nodo di chiusura. Successivamente basta applicare in modo iterativo la logica ed inserire all’interno dell’elemento (o nodo) Ambasciata tutti gli elementi di cui avrò bisogno. http: //www. itiserale. it

Formato XML <? xml version="1. 0" encoding="utf-8"? > <Ambasciate> <Ambasciata> <Nome. Ente>Amb. d'Italia</Nome. Ente>

Formato XML <? xml version="1. 0" encoding="utf-8"? > <Ambasciate> <Ambasciata> <Nome. Ente>Amb. d'Italia</Nome. Ente> <Tipo. Ente>Ambasciata</Tipo. Ente> <Nazione>Russia</Nazione> <Presidiato>true</Presidiato> <Incorporato>true</Incorporato> <Capitale>Mosca</Capitale> <Nome>Andrej</Nome> <Cognome>Mashekno</Cognome> <Sesso>M</Sesso> <Eta>56</Eta> <Indirizzo>Puskin, 1</Indirizzo> <Citta>Mosca</Citta> <Tipo. Visto>Turistico</Tipo. Visto> <Durata. Visto>45 gg</Durata. Visto> <Numero. Uomini>Unità massime: 10</Numero. Uomini> </Ambasciata> <Nome. Ente>Amb. d'Italia</Nome. Ente> <Tipo. Ente>Ambasciata</Tipo. Ente> <Nazione>Cina</Nazione> <Presidiato>true</Presidiato> <Incorporato>true</Incorporato> <Capitale>Pechino</Capitale> <Nome>Lin Pan</Nome> <Cognome>Jong</Cognome> <Sesso>M</Sesso> <Eta>39</Eta> <Indirizzo>Pihon Kon, 1</Indirizzo> <Citta>Pechino</Citta> <Tipo. Visto>Turistico</Tipo. Visto> <Durata. Visto>45 gg</Durata. Visto> <Numero. Uomini>Unità massime: 10</Numero. Uomini> </Ambasciata> </Ambasciate> Inserisco un elenco di elementi con i rispettivi nodi di apertura e chiusura tra i quali è presente la relativa informazione. <Nome. Ente> Amb. D’Italia </Nom. Ente> Scrivere il blocco su tre righe o su una sola riga è la stessa identica cosa. http: //www. itiserale. it

Scambio file XML Il server serializza le informazioni in un file formato XML tramite

Scambio file XML Il server serializza le informazioni in un file formato XML tramite “LINQ TO XML” <? xml version="1. 0" encoding="utf-8"? > <Ambasciate> <Ambasciata> <Nome. Ente>Amb. d'Italia</Nome. Ente> <Tipo. Ente>Ambasciata</Tipo. Ente> <Nazione>Russia</Nazione> <Presidiato>true</Presidiato> <Incorporato>true</Incorporato> <Capitale>Mosca</Capitale> <Nome>Andrej</Nome> <Cognome>Mashekno</Cognome> <Sesso>M</Sesso> <Eta>56</Eta> <Indirizzo>Puskin, 1</Indirizzo> <Citta>Mosca</Citta> <Tipo. Visto>Turistico</Tipo. Visto> <Durata. Visto>45 gg</Durata. Visto> <Numero. Uomini>Unità massime: 10</Numero. Uomini> </Ambasciata> <Nome. Ente>Amb. d'Italia</Nome. Ente> <Tipo. Ente>Ambasciata</Tipo. Ente> <Nazione>Cina</Nazione> <Presidiato>true</Presidiato> <Incorporato>true</Incorporato> <Capitale>Pechino</Capitale> <Nome>Lin Pan</Nome> <Cognome>Jong</Cognome> <Sesso>M</Sesso> <Eta>39</Eta> <Indirizzo>Pihon Kon, 1</Indirizzo> <Citta>Pechino</Citta> <Tipo. Visto>Turistico</Tipo. Visto> <Durata. Visto>45 gg</Durata. Visto> <Numero. Uomini>Unità massime: 10</Numero. Uomini> </Ambasciata> </Ambasciate> http: //www. itiserale. it La macchina Microsoft Windows riceve il file XML dal server linux e procede alla deserializzazione del contenuto del file per visualizzare i dati. Il file può essere ricevuto in molti modi, dal download diretto alla posta elettronica.

XDocument Questa classe è fondamentale perché rappresenta l’intero documento XML su cui il programmatore

XDocument Questa classe è fondamentale perché rappresenta l’intero documento XML su cui il programmatore può andare ad inserire i vari elementi (nodi) che interessano con i successivi dati. L’impiego di tale classe rende molto flessibile la gestione dei formati XML in ambiente C#. XDocument My. Doc. Xml = new XDocument(. . nodi. . ); var My. Doc. Xml = new XDocument(. . nodi. . ); http: //www. itiserale. it Local Type Inference

XElement Questa classe è fondamentale per la creazione di nodi XML all’interno dell’intera struttura

XElement Questa classe è fondamentale per la creazione di nodi XML all’interno dell’intera struttura ad albero. Un oggetto XElement può essere nidificato all’interno di altri oggetti XElement in modo da costruire la gerarchia che si vuole realizzare. XElement nodo = new XElement(“Ambasciate”); XElement nodo = new XElement(“Ambasciate”, new XElement(“Ambasciata”, new XElement(“Nome. Ente”) ) http: //www. itiserale. it );

Serializzazione con LINQ TO XML Definizione del documento XML con il local type inference

Serializzazione con LINQ TO XML Definizione del documento XML con il local type inference Definizione del root element Ambasciate all’interno del documento xml var Documento. XML = new XDocument ( Definizione iterativa dei nodi Ambasciata grazie a LINQ TO XML new XElement ( Lista di oggetti Ambasciata "Ambasciate", from Embassy in this. Oggetto. Liste. Lista. Di. Classi. Ambasciata select new XElement("Ambasciata", new XElement("Nome. Ente", Embassy. Nome. Ente), new XElement("Tipo. Ente", Embassy. Tipo. Ente), Definizione dei nodi interni new XElement("Nazione", Embassy. Nazione), di Ambasciata new XElement("Presidiato", Embassy. Presidiato), new XElement("Incorporato", Embassy. Incorporato), new XElement("Capitale", Embassy. Capitale), new XElement("Nome", Embassy. Nome), new XElement("Cognome", Embassy. Cognome), new XElement("Sesso", Embassy. Sesso), new XElement("Eta", Embassy. Eta), new XElement("Indirizzo", Embassy. Indirizzo), new XElement("Citta", Embassy. Citta), new XElement("Tipo. Visto", Embassy. Tipo. Visto), new XElement("Durata. Visto", Embassy. Durata. Visto), new XElement("Numero. Uomini", Embassy. Numero. Uomini) ) ) ); Serializzazione dell’intero documento XML presente nello HEAP nel file di testo chiamato Ambasciata. xml all’interno della directory c: temp Documento. XML. Save("c: \temp\Ambasciata. xml"); http: //www. itiserale. it

LINQ TO XML from Embassy in this. Oggetto. Liste. Lista. Di. Classi. Ambasciata Vediamo

LINQ TO XML from Embassy in this. Oggetto. Liste. Lista. Di. Classi. Ambasciata Vediamo in dettaglio LINQ TO XML. La clausola “from” dice a LINQ di prendere in considerazione ogni oggetto di tipo “Embassy” presente, grazie alla parola chiave “in”, all’interno di una lista di oggetti Ambasciata precedentemente inizializzata dall’utente. Tale riga di istruzione è logicamente equivalente ad un ciclo iterativo foreach, dato che LINQ parte dal primo elemento della lista ed arriva fino all’ultimo. Sarà compito del programmatore gestire ad ogni ciclo logico il singolo oggetto Ambasciata presente all’interno della lista. http: //www. itiserale. it

LINQ TO XML from Embassy in this. Oggetto. Liste. Lista. Di. Classi. Ambasciata select

LINQ TO XML from Embassy in this. Oggetto. Liste. Lista. Di. Classi. Ambasciata select new XElement("Ambasciata", new XElement("Nome. Ente", Embassy. Nome. Ente), …. . La parola chiave “select” permette di gestire ogni singolo elemento della lista ossia ogni oggetto Ambasciata, mentre con la parola chiave “new” viene creato nello HEAP un nodo XML Ambasciata all’interno del quale successivamente vengono creati una serie di nodi XML come “Nome. Ente”. Non dimenticate che tutti i nodi sono creati sempre all’interno di un documento XML rappresentato da un oggetto di tipo classe XDocument precedentemente creato. Per accedere ai dati membro dell’oggetto Ambasciata si usa la variabile Embassy presente dopo la parola chiave “from” ed il rispettivo metodo get “Nome. Ente” della classe Ambasciata. http: //www. itiserale. it

Salvataggio del documento XML Documento. XML. Save("c: \temp\Ambasciata. xml"); Grazie al metodo “Save” dell’oggetto

Salvataggio del documento XML Documento. XML. Save("c: \temp\Ambasciata. xml"); Grazie al metodo “Save” dell’oggetto chiamato “Documento. XML” di tipo classe XDocument, è possibile serializzare tutto il contenuto della struttura ad albero XML all’interno di un file di testo di propria scelta. Il doppio “\” serve per indicare a C# di non considerare il secondo carattere come escape ma come semplice carattere “” necessario per impostare un path in ambiente Microsoft Windows. http: //www. itiserale. it

Deserializzazione con LINQ TO XML Dal Caricamento documentonello XMLHEAP scelgodella il root struttura element

Deserializzazione con LINQ TO XML Dal Caricamento documentonello XMLHEAP scelgodella il root struttura element XML Ambasciate presente con nel file il metodo Ambasciata. xml “Element” nel e poi documento successivamente XML tramite rappresentato il metododall’oggetto “Elements”Documento. XML leggo in modo iterativo utilizzando i singoli il local nodi type Ambasciata. inference var Documento. XML= XDocument. Load("c: \temp\Ambasciata. xml"); var query = from Embassy in Documento. XML. Element("Ambasciate"). Elements("Ambasciata") Con la “select” si seleziona l’oggetto Ambasciata corrente mentre con la “new” si crea un nuovo oggetto select new nello HEAP di tipo “Anonymous type” ossia un tipo <T> { Nome. Ente = Embassy. Element("Nome. Ente"). Value, Tipo. Ente = Embassy. Element("Tipo. Ente"). Value, Nazione = Embassy. Element("Nazione"). Value, I dati membro Presidiato = Convert. To. Boolean(Embassy. Element("Presidiato"). Value), del nuovo oggetto vengono popolati Incorporato = Convert. To. Boolean(Embassy. Element("Incorporato"). Value), leggendo il valore Capitale = Embassy. Element("Capitale"). Value, con la proprietà “value” Nome = Embassy. Element("Nome"). Value, direttamente dal nodo XML tramite il metodo Cognome = Embassy. Element("Cognome"). Value, “Element”. Sesso = Embassy. Element("Sesso"). Value, Eta = Embassy. Element("Eta"). Value, Indirizzo = Embassy. Element("Indirizzo"). Value, Citta = Embassy. Element("Citta"). Value, Tipo. Visto = Embassy. Element("Tipo. Visto"). Value, Durata. Visto = Embassy. Element("Durata. Visto"). Value, Numero. Uomini = Embassy. Element("Numero. Uomini"). Value }; Alla fine del ciclo logico effettuato da LINQ, nella variabile query viene inferito il risultato ossia una lista di oggetti “Anonymous Type” http: //www. itiserale. it

Il Tipo Anonimo var query = from Embassy ………. La variabile “query” tramite il

Il Tipo Anonimo var query = from Embassy ………. La variabile “query” tramite il local type inference viene inferita con un tipo Anonimo direttamente dal compilatore C#. Questa è una caratteristica che trovate a partire da C# 3. 0 di Visual Studio 2008 e release successive. La variabile “query” eredita l’interfaccia IEnumerable che gli permette di venire scandita elemento dopo elemento come un vettore o una lista di dati. <T> indica “Anonymous Type”. http: //www. itiserale. it

Local type inference e Data. Grid. View grd. Dati. Ambasciata. Data. Source = query.

Local type inference e Data. Grid. View grd. Dati. Ambasciata. Data. Source = query. To. List(); La variabile “query” sottoposta al local type inference eredita l’interfaccia IEnumerable. Per copiare tutti i dati degli oggetti presenti in “query” dobbiamo passare in rassegna oggetto dopo oggetto e tramite i metodi get automatici di C# copiare le informazioni nella griglia dati di tipo Data. Grid. View. La sorgente dati di una griglia può essere una lista di tipi anonimi ossia “List<T>”, quindi dobbiamo creare in quest’ultima degli oggetti prelevati direttamente dalla variabile “query” la quale è accessibile grazie all’interfaccia IEnumerable. Per creare gli oggetti nella sorgente dati della griglia uso il metodo esteso “To. List” della variabile inferita “query”. http: //www. itiserale. it

Extension Method (metodi estesi) A partire da C# 3. 0 di Visual Studio 2008,

Extension Method (metodi estesi) A partire da C# 3. 0 di Visual Studio 2008, è possibile utilizzare i metodi estesi, conosciuti con il nome di Extension Methods. Vediamo un esempio di metodo esteso così da chiari tutti i dubbi. public static class Esempio { public static string Maiuscolo(string s) { return s. To. Upper(); } } static void Main(string [ ] args) { Console. Write. Line(Esempio. Maiuscolo(“ciao mondo”)); } http: //www. itiserale. it

Extension Method (metodi estesi) public static class Esempio Devo inserire la clausola “this” prima

Extension Method (metodi estesi) public static class Esempio Devo inserire la clausola “this” prima del tipo del parametro { public static string Maiuscolo 2(this string s) { return s. To. Upper(); } Applico il metodo statico “Maiuscolo 2” direttamente al tipo “string”. } static void Main(string [ ] args) { Console. Write. Line(“io sono esteso”. Maiuscolo 2()); } http: //www. itiserale. it