Lekce 7 - Čtení XML SAXem v C# .NET
V minulé lekci, Úvod do XML a zápis SAXem v C# .NET, jsme si představili formát XML a ukázali si, jak pomocí SAXu vytvořit jednoduché XML.
V dnešním C# .NET tutoriálu navážeme na lekci Úvod do XML a zápis SAXem v C# .NET a napíšeme si proces opačný, tedy načtení XML souboru s uživateli a sestavení příslušné objektové struktury (listu uživatelů).
Čtení XML přes SAX
Než se pustíme do samotného čtení dat ze souboru, připravíme si
aplikaci. Založme si konzolovou aplikaci XmlSaxCteni
.
Třída Uzivatel
Přidejme si třídu Uzivatel
:
class Uzivatel { public string Jmeno { get; private set; } public int Vek { get; private set; } public DateTime Registrovan { get; private set; } public Uzivatel(string jmeno, int vek, DateTime registrovan) { Jmeno = jmeno; Vek = vek; Registrovan = registrovan; } public override string ToString() { return Jmeno; } }
Soubor uzivatele.xml
Do složky s aplikací na cestě .../bin/debug/
vložíme XML
soubor uzivatele.xml
s tímto obsahem:
<?xml version="1.0" encoding="utf-8"?> <uzivatele> <uzivatel vek="22"> <jmeno>Pavel Slavík</jmeno> <registrovan>21.3.2000</registrovan> </uzivatel> <uzivatel vek="31"> <jmeno>Jan Novák</jmeno> <registrovan>30.10.2012</registrovan> </uzivatel> <uzivatel vek="16"> <jmeno>Tomáš Marný</jmeno> <registrovan>12.1.2011</registrovan> </uzivatel> </uzivatele>
Aplikaci máme připravenou, můžeme se tedy pustit do čtení dat ze
souboru. Kód budeme kvůli jednoduchosti psát do metody
Main()
.
Kolekce uživatelů
Uživatele budeme chtít načíst do nějaké kolekce. Prvním kódem v
metodě Main()
tedy bude vytvoření prázdného listu
uživatelů:
List<Uzivatel> uzivatele = new List<Uzivatel>();
Třída XmlReader
Ke čtení XML přes SAX nám .NET framework poskytuje třídu
XmlReader
. Pojďme si vytvořit její instanci:
using (XmlReader xr = XmlReader.Create(@"uzivatele.xml")) { }
Nezapomeneme si do jmenných prostorů přidat
using System.Xml
.
K vytvoření instance využíváme tovární metodu Create()
,
jejímž parametrem je název souboru. Vše jsme dali do bloku
using
, který se nám postará o uzavření souboru. Veškerý
další kód budeme psát do tohoto bloku using
.
Pomocné proměnné
Připravíme si tyto pomocné proměnné pro vlastnosti uživatele:
string jmeno = ""; int vek = 0; DateTime registrovan = DateTime.Now; string element = "";
Tyto proměnné potřebujeme proto, že nemůžeme ukládat přímo do
instance, jelikož vlastnosti jsou read-only
. Druhou možností
může být povolit modifikaci zvenčí, tím ale ztrácíme část
zapouzdření. Vlastnosti naplníme výchozími hodnotami, které tam zůstanou
v případě, že daná hodnota nebude v XML zapsána. Budeme potřebovat někam
ukládat jméno aktuálního elementu, proto si definujeme stringovou proměnnou
element
.
Metoda Read()
Začneme načítat soubor. XmlReader
načítá soubor řádek po
řádku, odshora dolů. Na jeho instanci zavoláme metodu
Read()
:
while (xr.Read())
{
}
Metoda Read()
nám při každém zavolání načte další
takzvaný uzel.
Uzlem může být element, případně atribut, textová hodnota elementu nebo komentář.
Nás budou zajímat uzly Element
, Text
a
EndElement
. Pokud je čtečka na konci souboru, vrátí metoda
Read()
hodnotu false
, v opačném případě vrací
true
.
Načítání uzlů
Postoupíme tedy k postupnému načítání všech uzlů v dokumentu pomocí
while
cyklu, do kterého si vložíme tyto podmínky:
if (xr.NodeType == XmlNodeType.Element) { } else if (xr.NodeType == XmlNodeType.Text) { }
Na instanci XmlReader
máme několik užitečných vlastností.
My využíváme vlastnost NodeType
, ve které je uložen typ
aktuálního uzlu, na kterém se čtečka nachází. Nás nyní zajímají dva
typy uzlů, kterými jsou Element
a Text
.
Načtení elementu
Do první podmínky si nyní vložíme tuto reakci na načtení elementu:
element = xr.Name; if (element == "uzivatel") { vek = int.Parse(xr.GetAttribute("vek")); }
Zde provádíme dvě akce. Klíčovou akcí je uložení názvu
elementu do proměnné element
, abychom byli schopni v
druhé podmínce zjistit, kterého elementu je text, který právě čteme.
Pokaždé, když narazíme na element uzivatel
, načteme atribut
věk pomocí metody GetAttribute()
, jejímž parametrem je
název atributu.
Zpracování hodnoty elementu
Přejděme do druhé podmínky, tedy do zpracování hodnoty elementu:
switch (element) { case "jmeno": jmeno = xr.Value; break; case "registrovan": registrovan = DateTime.Parse(xr.Value); break; }
Zde využíváme předem uložené hodnoty názvu elementu, kterou si
vložíme do konstrukce switch
. Podle elementu ukládáme hodnotu
do dané proměnné, ke které přistupujeme přes vlastnost
Value
.
Načtení uzavíracího elementu
Již jsme velmi blízko přidání uživatele. Jeho přidání nastane ve
chvíli načtení uzavíracího elementu </uzivatel>
. K
našim dvěma podmínkám tedy přidáme třetí:
else if ((xr.NodeType == XmlNodeType.EndElement) && (xr.Name == "uzivatel")) uzivatele.Add(new Uzivatel(jmeno, vek, registrovan));
Máme hotovo
Kompletní kód načtení souboru
Pro jistotu si uveďme kompletní kód načtení souboru:
using (XmlReader xr = XmlReader.Create(@"uzivatele.xml")) { string jmeno = ""; int vek = 0; DateTime registrovan = DateTime.Now; string element = ""; while (xr.Read()) { if (xr.NodeType == XmlNodeType.Element) { element = xr.Name; if (element == "uzivatel") { vek = int.Parse(xr.GetAttribute("vek")); } } else if (xr.NodeType == XmlNodeType.Text) { switch (element) { case "jmeno": jmeno = xr.Value; break; case "registrovan": registrovan = DateTime.Parse(xr.Value); break; } } else if ((xr.NodeType == XmlNodeType.EndElement) && (xr.Name == "uzivatel")) uzivatele.Add(new Uzivatel(jmeno, vek, registrovan)); } }
Výpis uživatelů
Zbývá uživatele vypsat, abychom věděli, že jsme je načetli správně.
Upravíme si metodu ToString()
ve třídě Uzivatel
tak, aby vracela všechny hodnoty:
public override string ToString() { return String.Format("{0}, {1}, {2}", Jmeno, Vek, Registrovan.ToShortDateString()); }
Na konec metody Main()
přidáme kód pro vypsání
uživatelů:
foreach (Uzivatel u in uzivatele) { Console.WriteLine(u); } Console.ReadKey();
Testování
Po spuštění aplikace se nám vypíšou všichni uživatelé:
Konzolová aplikace
Pavel Slavík, 22, 21.3.2000
Jan Novák, 31, 30.10.2012
Tomáš Marný, 16, 12.1.2011
V příští lekci, Práce s XML soubory pomocí DOM v C# .NET, budeme pracovat s XML soubory pomocí DOM
(XmlDocument
), tedy zapisovat je a číst objektově jako stromovou
strukturu.
Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 736x (22.42 kB)
Aplikace je včetně zdrojových kódů v jazyce C#