Leggere e visualizzare file XML con C# (C sharp): qualche esempio
Pubblicato da Davide, martedì 13 luglio 2010 1 Commento »
C# è ormai un linguaggio diffuso, Visual Studio volenti o nolenti è un IDE collaudato e comodo anche per lo sviluppo di applicazioni web. E quando si parla di web, si parla spesso di XML.
Leggere i dati di un documento XML è un’operazione semplice e veloce, farli visualizzare su una pagina web è altrettanto rapido, ma è bene sapere alcune nozioni per potersi muovere con tranquillità e sicurezza.
Andiamo con ordine e vediamo subito un esempio di un file XML che vogliamo trattare:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<DataSet>
<data>
<period>2010-06-06</period>
<logunit id="myID">Milano</logunit>
<entered matcode="ABC001">100</entered>
<produced matcode="ABC002">101</produced>
<delivered matcode="ABC002">100</delivered>
<description>Caramelline alla fragola</description>
<updated>2010-06-06T13:05:21+01:00</updated>
<note>tante belle cose..</note>
</data>
<data>
[..]
</data>
</DataSet>
Questo file potrebbe rappresentare dei dati produttivi, riguardanti ad esempio i materiali entrati in magazzino, i materiali prodotti e il venduto.
Il modo più rapido e banale per leggere questo file e farlo visualizzare su una pagina ASPX è tramite il seguente codice:
DataSet ds = new DataSet();
ds.ReadXml(@"C:\test.xml", XmlReadMode.Auto);
DataView MyDataView = new DataView(ds.Tables[0]);
MyDataGrid.DataSource = MyDataView;
MyDataGrid.DataBind();
Il codice non fa altro che creare un nuovo DataSet per contenere i dati che andremo a leggere, leggere il file tramite il metodo ReadXml(), creare una DataView con la tabella creata nel dataset e assegnare quest’ultima come DataSource per la DataGrid.
All’interno della pagina .aspx ci sarà quindi una DataSource così fatta:
<asp:DataGrid id="MyDataGrid" runat="server" >
<HeaderStyle CssClass="th">
</HeaderStyle>
</asp:DataGrid>
Tralasciamo lo stile attribuito alla testata della datagrid, ciò che è importante in questo caso è solo l’ID.
Così facendo però ottengo una tabella di questo tipo:
period | data_Id | description | updated | note |
2010-06-06 | 0 | Caramelline alla fragola | 2010-06-16T13:05:21+01:00 | tante belle cose.. |
E tutti gli altri dati che fine hanno fatto? Sono stati salvati in altre tabelle del DataSet, assieme a tutti gli attributi dell’xml; queste tabelle avranno come riferimento il data_Id e potrò utilizzarle come meglio credo.
Se infatti cambiamo il primo codice, mettendo una tabella diversa, in questo modo:
DataView MyDataView = new DataView(ds.Tables[1]);
Verrà visualizzata una pagina con la seguente tabella:
id | logunit_Text | data_Id |
MyID | Milano | 0 |
Se cambio e metto la terza tabella:
DataView MyDataView = new DataView(ds.Tables[2]);
Il risultato sarà:
matcode | entered_Text | data_Id |
ABC001 | 100 | 0 |
Mentre per le tabelle successive, avrò questi risultati visualizzati:
matcode | produced_Text | data_Id |
ABC002 | 101 | 0 |
matcode | delivered_Text | data_Id |
ABC002 | 100 | 0 |
Incrociando queste tabelle attraverso il campo data_Id potrei ricavare tutti i dati contenuti nell’XML, attributi e testi all’interno dei tag.
Il mio obiettivo era però quello di far visualizzare questi dati senza gli attributi riportati nell’XML. Ciò che mi interessa sono solo i dati riportati all’interno dei tag. Vorrei avere un risultato di questo tipo:
period | description | updated | note | logunit | entered | produced | delivered |
2010-06-06 | Caramelline alla fragola | 2010-06-16T13:05:21+01:00 | tante belle cose.. | Milano | 100 | 101 | 100 |
In questo caso potrebbe fare al caso nostro l’ XML Schema. Si tratta di un file con estensione XSD, che descrive i dati contenuti in un file XML. Ogni file XML può avere uno schema associato che lo descrive. Esistono diversi tool che possono creare un file XSD a partire da un XML, uno di questi, che trovo molto pratico è quello di Flame-Ware completamente on-line.
Il nostro file XML iniziale potrebbe essere descritto da questo XSD, supponendo che tutti i campi siano stringe.
<?xml version="1.0"?>
<!-- Generated using Flame-Ware Solutions XML-2-XSD v2.0 at http://www.flame-ware.com/Products/XML-2-XSD/ -->
<xs:schema id="DataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="DataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="data">
<xs:complexType>
<xs:sequence>
<xs:element name="period" type="xs:string" minOccurs="0" />
<xs:element name="description" type="xs:string" minOccurs="0" />
<xs:element name="updated" type="xs:string" minOccurs="0" />
<xs:element name="note" type="xs:string" minOccurs="0" />
<xs:element name="logunit" nillable="true" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent msdata:ColumnName="logunit_Text" msdata:Ordinal="1">
<xs:extension base="xs:string">
<xs:attribute name="id" type="xs:string" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="entered" nillable="true" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent msdata:ColumnName="entered_Text" msdata:Ordinal="1">
<xs:extension base="xs:string">
<xs:attribute name="matcode" type="xs:string" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="produced" nillable="true" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent msdata:ColumnName="produced_Text" msdata:Ordinal="1">
<xs:extension base="xs:string">
<xs:attribute name="matcode" type="xs:string" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="delivered" nillable="true" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent msdata:ColumnName="delivered_Text" msdata:Ordinal="1">
<xs:extension base="xs:string">
<xs:attribute name="matcode" type="xs:string" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
Per associare questo schema al file XML, è necessario dichiararlo nell’intestazione, in questo modo:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<DataSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="schema.xsd">
<data>
<period>2010-06-06</period>
<logunit id="myID">Milano</logunit>
<entered matcode="ABC001">100</entered>
<produced matcode="ABC002">101</produced>
<delivered matcode="ABC002">100</delivered>
<description>Caramelline alla fragola</description>
<updated>2010-06-06T13:05:21+01:00</updated>
<note>tante belle cose..</note>
</data>
</DataSet>
Così facendo però, se rilanciamo la pagina costruita in precedenza, il risultato sarà identico: un unico dataset con diverse tabelle collegate tra loro dal campo data_Id.
Quindi? La soluzione c’è. Dobbiamo solo definire uno schema XSD semplificato all’interno dell’XML stesso. In questo modo:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<DataSet>
<xs:schema id="NewDataset" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="NewDataset" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="data">
<xs:complexType>
<xs:sequence>
<xs:element name="period" type="xs:string" minOccurs="0" />
<xs:element name="description" type="xs:string" minOccurs="0" />
<xs:element name="updated" type="xs:string" minOccurs="0" />
<xs:element name="note" type="xs:string" minOccurs="0" />
<xs:element name="logunit" type="xs:string" minOccurs="0" />
<xs:element name="entered" type="xs:string" minOccurs="0" />
<xs:element name="produced" type="xs:string" minOccurs="0" />
<xs:element name="delivered" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
<data>
<period>2010-06-06</period>
<logunit id="myID">Milano</logunit>
<entered matcode="ABC001">100</entered>
<produced matcode="ABC002">101</produced>
<delivered matcode="ABC002">100</delivered>
<description>Caramelline alla fragola</description>
<updated>2010-06-06T13:05:21+01:00</updated>
<note>tante belle cose..</note>
</data>
<data>
<period>2010-06-06</period>
<logunit id="myID">Milano</logunit>
<entered matcode="ABC001">100</entered>
<produced matcode="ABC002">101</produced>
<delivered matcode="ABC002">100</delivered>
<description>Caramelline alla fragola</description>
<updated>2010-06-06T13:05:21+01:00</updated>
<note>tante belle cose..</note>
</data>
</DataSet>
Il risultato finale sarà quindi una DataGrid che può essere visualizzata come sotto, utilizzando pari pari il codice C# definito all’inizio di questo articolo.
period | description | updated | note | logunit | entered | produced | delivered |
2010-06-06 | Caramelline alla fragola | 2010-06-16T13:05:21+01:00 | tante belle cose.. | Milano | 100 | 101 | 100 |
Buon divertimento con l’XML..
1 Commento »
Puoi lasciare un tuo commento, oppure fare un trackback dal tuo sito.
Lascia il tuo commento
1
I migliori post della settimana #75 | Web Developer / Web Designer / SEO Specialist / Napoli :: EmaWebDesign - Pubblicato il 18 07 2010 alle 14:07
[...] 01) Leggere e visualizzare file XML con C# (C sharp): qualche esempio [...]