LINQ (acronimo per
Language INtegrated Query) è una delle tecnologie più interessanti introdotte nel
Framework .NET 3.5. LINQ permette la ricerca entro una qualunque struttura dati direttamente dal codice di un programma ad alto livello, integrandosi con gli altri meccanismi già presenti dentro i linguaggi di .NET. L'architettura di LINQ, come è illustrato nell'immagine qui di seguito, evidenzia come sia possibile sfruttare questa estensione del linguaggio in scenari differenti:
LINQ to SQL, LINQ to DATASET , LINQ to ENTITIES ed infine LINQ to XML.
In questo breve Tip viene presentato un uso particolare di
LINQ: leggere attraverso un codice compatto un file
XML e usarlo come strumento per passare parametri a run-time ad un programma.
Le funzionalità di
LINQ to XML sono contenute nel namespace
System.Xml.Linq che deve quindi essere importato. Le principali classi che possiamo individuare all’interno di questo namespace sono:
•
XDocument: permette di definire un documento Xml
•
XElement: è un elemento Xml che al suo interno può inglobare attributi
•
XAttribute: attributi del file Xml
•
XName: è il nome dell’elemento o di un attributo Xml
Il file
XML usato nell’esempio è il seguente e rappresenta un file di parametri per un modulo di un applicativo reale, che, in un contesto di building automation deve periodicamente colloquiare con vari dispositivi per poi riversare i dati raccolti entro un DBMS Oracle Express e deve essere installato su numerosi PC diversi, in ciascuno dei quali le impostazioni devono essere fatte durante l’installazione.
<?xml version="1.0" encoding="utf-8"?>
<ConfigurationsFiles>
<ConfigurationsFile>
<DbOracleConnection>Provider=OraOLEDB.Oracle.1;Data Source=192.168.200.12:1521/xe;
Persist Security Info=True;Password=Prova;User ID=Prova</DbOracleConnection >
<Centralina_1>0010</Centralina_1>
<Plc_config>12AC</Plc_config>
<Locazione>122a2</Locazione>
</ConfigurationsFile>
</ConfigurationsFiles>
In particolare, i dati da estrarre dal file di configurazione sono la connection string verso il DBMS, contenuta nel tag
DbOracleConnection, il codice della Centralina, contenuto nel tag
Centralina_1, il codice della configurazione del PLC, contenuto nel tag
Plc_config e la dislocazione fisica del PC industriale che ospita l’applicativo, contenuta nel tag
Locazione. Nell’esempio è presente un solo ConfigurationFile, tag che rappresenta un blocco di parametri consistenti, ma potrebbero esistere entro lo stesso file più blocchi.
Il nostro scopo è poter leggere il contenuto del file
XML per utilizzare i valori presenti nei nodi, come "costanti" a run-time all’interno della nostra applicazione richiamandole semplicemente con un’istruzione compatta.
Il primo passo è creare una struttura dati che contenga il set di parametri, che chiameremo
Impostazioni:
namespace GestioneDatiXML.Entity
{
public class Impostazioni
{
// ATTRIBUTI INTERNI CON I VALORI DI DEFAULT
private string _dbOracleConnection = "Provider=OraOLEDB.Oracle.1;Data Source=192.168.1.16:1521/xe;Persist Security Info=True;Password=testpwd;User ID=test";
private string _centralina_1 = "0001";
private string _plc_config = "1A00";
private string _locazione = "122a0";
// PROPRIETA' PER ACCEDERE AGLI ATTRIBUTI
public string DbOracleConnection
{
get { return _dbOracleConnection; }
set { _dbOracleConnection = value; }
}
public string Centralina_1
{
get { return _centralina_1 ;}
set { _centralina_1 = value; }
}
public string Plc_config
{
get { return _plc_config; }
set { _plc_config = value; }
}
public string Locazione
{
get { return _locazione ;}
set { _locazione = value; }
}
} // end class Impostazioni
} // end namespace
Poi serve creare l'elemento che legge i parametri precedentementi illustrati dal file
XML:
public class XmlDataReader
{
// ATTRIBUTI per la lettura
static String fileName = "Gestion.xml";
static String fullFileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName);
public static Impostazioni GetImpostazioni()
{
Impostazioni imp = (from c in XDocument.Load(fullFileName)
.Descendants("ConfigurationsFile")
select new Impostazioni
{
DbOracleConnection = c.Element("DbOracleConnection").Value,
Centralina_1 = c.Element("Centralina_1").Value,
Plc_config = c.Element("Plc_config").Value,
Locazione = c.Element("Locazione").Value,
}).FirstOrDefault();
return imp;
} // end method
//public static GetUnElemento con il suo nome
} // end class XmlDataReader
Il metodo
.FirstOrDefault() ci restituisce il primo elemento di una sequenza o un valore predefinito se la sequenza non contiene elementi.
Ora non ci resta altro che utilizzare all’interno del programma i dati letti con queste semplici istruzioni:
//Prelevo i dati come fossero delle costanti note da un'opportuno file di settaggio
Impostazioni imp = XmlDataReader.GetImpostazioni();
txtCentralina.Text = imp.Centralina_1;
txtOracle.Text = imp.DbOracleConnection;
txtPlc.Text = imp.Plc_config;
txtLocazione.Text = imp.Locazione;
Si è quindi mostrato com’è possibile sfruttare le potenzialità di
LINQ to XML per leggere strutture dati di settaggi strutturate e richiamarle all’interno della nostra applicazione in maniera rapida e veloce come "semplici costanti" come mostra la seguente immagine.
Hanno collaborato a questo tip anche
Giulio Destri ed
Alberto Picca