7. diel - Čítanie XML SAXom v C# .NET
V minulej lekcii, Úvod do XML a zápis SAXom v C# .NET, sme si predstavili formát XML a ukázali si, ako pomocou SAXu vytvoriť jednoduché XML.
V dnešnom C# .NET tutoriále nadviažeme na lekciu Úvod do XML a zápis SAXom v C# .NET a napíšeme si proces opačný, teda načítanie XML súboru s užívateľmi a zostavenie príslušnej objektovej štruktúry (listu užívateľov).
Čítanie XML cez SAX
Než sa pustíme do samotného čítania dát zo súboru, pripravíme si
aplikáciu. Založme si konzolovú aplikáciu XmlSaxReading
.
Trieda User
Pridajme si triedu User
:
class User { public string Name { get; private set; } public int Age { get; private set; } public DateTime Registered { get; private set; } public User(string name, int age, DateTime registered) { Name = name; Age = age; Registered = registered; } public override string ToString() { return Name; } }
Súbor users.xml
Do priečinka s aplikáciou na ceste .../bin/debug/
vložíme
XML súbor users.xml
s týmto obsahom:
<?xml version="1.0" encoding="utf-8"?> <users> <user age="22"> <name>John Smith</name> <registered>21.3.2000</registered> </user> <user age="31"> <name>James Brown</name> <registered>30.10.2012</registered> </user> <user age="16"> <name>Tom Hanks</name> <registered>12.1.2011</registered> </user> </users>
Aplikáciu máme pripravenú, môžeme sa teda pustiť do čítania dát zo
súboru. Kód budeme kvôli jednoduchosti písať do metódy Main()
v triede Program
.
Kolekcia používateľov
Užívateľa budeme chcieť načítať do nejakej kolekcie. Prvým kódom v
metóde Main()
teda bude vytvorenie prázdneho listu
užívateľov:
List<User> users = new List<User>();
Trieda XmlReader
Na čítanie XML cez SAX nám .NET framework poskytuje triedu
XmlReader
. Poďme si vytvoriť jej inštanciu:
using (XmlReader xr = XmlReader.Create(@"users.xml")) { }
Nezabudneme si do menných priestorov pridať
using System.Xml
.
Na vytvorenie inštancie využívame továrenskú metódu
Create()
, ktorej parametrom je názov súboru. Všetko sme dali do
bloku using
, ktorý sa nám postará o uzavretie súboru. Všetok
ďalší kód budeme písať do tohto bloku using
.
Pomocné premenné
Pripravíme si tieto pomocné premenné pre vlastnosti používateľa:
string name = ""; int age = 0; DateTime registered = DateTime.Now; string element = "";
Tieto premenné potrebujeme preto, že nemôžeme ukladať priamo do
inštancie, pretože vlastnosti sú read-only
. Druhou možnosťou
môže byť povoliť modifikáciu zvonku, tým ale strácame časť zapuzdrenia.
Vlastnosti naplníme predvolenými hodnotami, ktoré tam zostanú v prípade,
že daná hodnota nebude v XML zapísaná. Budeme potrebovať niekam ukladať
meno aktuálneho elementu, preto si definujeme stringovú premennú
element
.
Metóda Read()
Začneme načítať súbor. XmlReader
načíta súbor riadok po
riadku, zhora nadol. Na jeho inštanciu zavoláme metódu
Read()
:
while (xr.Read())
{
}
Metóda Read()
nám pri každom zavolaní načíta ďalší
takzvaný uzol.
Uzlom môže byť element, prípadne atribút, textová hodnota elementu alebo komentár.
Nás budú zaujímať uzly Element
, Text
a
EndElement
. Ak je čítačka na konci súboru, vráti metóda
Read()
hodnotu false
, v opačnom prípade vracia
true
.
Načítanie uzlov
Postúpime teda k postupnému načítaniu všetkých uzlov v dokumente
pomocou while
cyklu, do ktorého si vložíme tieto podmienky:
if (xr.NodeType == XmlNodeType.Element) { } else if (xr.NodeType == XmlNodeType.Text) { }
Na inštancii XmlReader
máme niekoľko užitočných
vlastností. My využívame vlastnosť NodeType
, v ktorej je
uložený typ aktuálneho uzla, na ktorom sa čítačka nachádza. Nás teraz
zaujímajú dva typy uzlov, ktorými sú Element
a
Text
.
Načítanie elementu
Do prvej podmienky si teraz vložíme túto reakciu na načítanie elementu:
element = xr.Name; if (element == "user") { age = int.Parse(xr.GetAttribute("age")); }
Tu vykonávame dve akcie. Kľúčovou akciou je uloženie názvu
elementu do premennej element
, aby sme boli schopní v
druhej podmienke zistiť, ktorého elementu je text, ktorý práve čítame.
Zakaždým, keď narazíme na element user
, načítame atribút
age
pomocou metódy GetAttribute()
, ktorej parametrom
je názov atribútu.
Spracovanie hodnoty elementu
Prejdime do druhej podmienky, teda do spracovania hodnoty elementu:
switch (element) { case "name": name = xr.Value; break; case "registered": registered = DateTime.Parse(xr.Value); break; }
Tu využívame vopred uložené hodnoty názvu elementu, ktorú si vložíme
do konštrukcie switch
. Podľa elementu ukladáme hodnotu do danej
premennej, ku ktorej pristupujeme cez vlastnosť Value
.
Načítanie uzatváracieho elementu
Už sme veľmi blízko pridania používateľa. Jeho pridanie nastane vo
chvíli načítania uzatváracieho elementu </user>
. K našim
dvom podmienkam teda pridáme tretí:
else if ((xr.NodeType == XmlNodeType.EndElement) && (xr.Name == "user")) users.Add(new User(name, age, registered));
Máme hotovo
Kompletný kód načítania súboru
Pre istotu si uveďme kompletný kód v bloku using
:
using (XmlReader xr = XmlReader.Create(@"users.xml")) { string name = ""; int age = 0; DateTime registered = DateTime.Now; string element = ""; while (xr.Read()) { if (xr.NodeType == XmlNodeType.Element) { element = xr.Name; if (element == "user") { age = int.Parse(xr.GetAttribute("age")); } } else if (xr.NodeType == XmlNodeType.Text) { switch (element) { case "name": name = xr.Value; break; case "registered": registered= DateTime.Parse(xr.Value); break; } } else if ((xr.NodeType == XmlNodeType.EndElement) && (xr.Name == "user")) users.Add(new User(name, age, registered)); } }
Výpis užívateľov
Zostáva užívateľa vypísať, aby sme vedeli, že sme ich načítali
správne. Upravíme si metódu ToString()
v triede
User
tak, aby vracala všetky hodnoty:
public override string ToString() { return String.Format("{0}, {1}, {2}", Name, Age, Registered.ToShortDateString()); }
Na koniec metódy Main()
v triede Program
pridáme
kód na vypísanie užívateľov:
foreach (User user in users) { Console.WriteLine(user); } Console.ReadKey();
Testovanie
Po spustení aplikácie sa nám vypíšu všetci používatelia:
Konzolová aplikácia
John Smith, 22, 21.03.2000
James Brown, 31, 30.10.2012
Tom Hanks, 16, 12.01.2011
V budúcej lekcii, Práca s XML súbormi pomocou DOM v C# .NET, budeme pracovať s XML súbormi pomocou DOM
(XmlDocument
), teda zapisovať ich a čítať objektovo ako
stromovú štruktúru.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 0x (39.04 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C#