NOVINKA - Online rekvalifikační kurz Python programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

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 ko­mentář. 

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#

 

Předchozí článek
Úvod do XML a zápis SAXem v C# .NET
Všechny články v sekci
Soubory v C# .NET
Přeskočit článek
(nedoporučujeme)
Práce s XML soubory pomocí DOM v C# .NET
Článek pro vás napsal David Hartinger
Avatar
Uživatelské hodnocení:
67 hlasů
David je zakladatelem ITnetwork a programování se profesionálně věnuje 15 let. Má rád Nirvanu, nemovitosti a svobodu podnikání.
Unicorn university David se informační technologie naučil na Unicorn University - prestižní soukromé vysoké škole IT a ekonomie.
Aktivity