4. Práce s XML souborem

4.1. Načítání z XML souboru

Vezměme si příklad, ve kterém budeme chtít vygenerovat HTML stránku s recepty uloženými v XML souboru. Data mají strukturu jako v kuchařce ze sekce Tvorba dokumentu. Data z XML souboru lze načíst opět různými způsoby. my použijeme třídu XmlTextReader, která umožňuje jednosměrné načítání dat. Aby tato data byla uchována v rozumné odpovídající struktuře, nabízí C# třídu XmlDocument.

[ukázka kódu]
using System.Xml;
...
XmlDocument myXml;

// xmlReader bude nacitat data ze souboru kucharka.xml
XmlTextReader xmlReader = new XmlTextReader("kucharka.xml");
myXml.Load(xmlReader);
...

4.2. Zpracování načtených dat

Nyní, když máme data načtená, můžeme s nimi pracovat.

Nejprve se ale podívejme na některé metody přístupu k datům v XmlDocument.

4.2.1. Metody přístupu k datům objektu XmlDocument

Tak, jak je dokument strukturován v XML souboru, můžeme přistupovat k jednotlivým elementům či atributům i my. Budeme chtít získat hodnotu elementu uvedeného v následujícím výpise XML souboru.

[ukázka kódu]
<?xml version="1.0" encoding="UTF-8"?>
<kucharka>
  <recept nazev="testovaci krme">
    <postup>---TENTO TEXT CHCEME ZISKAT---</postup>
  </recept>
</kucharka>

Vidíme v něm, že se zde nachází deklarace, následuje první - kořenový - element kucharka, následuje element-potomek recept a ten má element-potomka postup. Pokud chceme získat hodnotu elementu postup právě na této úrovni, v C# to provedeme následovně. XML soubor již máme načtený v instanci třídy XmlDocument s názvem myXml.

[ukázka kódu]
myXml.ChildNodes[1].ChildNodes[0].ChildNodes[0].InnerText;

Vlastnost ChildNodes vrací uzly-potomky předchozího uzlu. Operace myXml.ChildNodes[1] nám tedy vrátí uzel kucharka. Postupným zanořováním do stromu se dostaneme až k hledané hodnotě.

V praxi se ovšem stane, že nevíme, zda uzel, na který právě ukazujeme, je ten náš - tedy uzel postup. Naštěstí stačí ověřit, zda souhlasí jméno uzlu.

[ukázka kódu]
if(myXml.ChildNodes[1].ChildNodes[0].ChildNodes[0].Name == "postup")
  System.Console.WriteLine(myXml.ChildNodes[1].ChildNodes[0].ChildNodes[0].InnerText);

Díky podobným konstrukcím můžeme vytvořit libovolně hluboké zanoření do stromu XML dokumentu.

4.2.2. Generování HTML kódu ze souboru kucharka.xml

V předchozím odstavci jsme si objasnili základní metody přístupu k uzlům objektu XmlDocument. Nyní si vygenerujeme kuchařku tak, aby byla zobrazitelná a snadno čitelná v internetovém prohlížeči. Postupně si budeme vypisovat jednotlivé úseky metody Main() ve třídě XMLCtecka. Tato třída obsahuje kód pro generování HTML kódu.

Pro objasnění - metoda ZapisText(string text) do výsledného HTML souboru zapisuje jednotlivé řádky.

[ukázka kódu]
XMLCtecka ctecka = new XMLCtecka();
...
foreach(XmlNode receptNode in mainNode) {
  if(receptNode.Name == "recept") {
    // zapise nazev receptu
    ctecka.ZapisText("<h2>" + receptNode.Attributes["nazev"].Value + "</h2>");
    ctecka.ZapisText("\n<b>Potřebné přísady:</b>\n<ul>");
    
    // zacne vypisovat jednotlive prisady
    foreach(XmlNode node in receptNode) {
        // muze zde byt i uzel postup
        if(node.Name == "ingredience") {
            ctecka.ZapisText("\n<li>");
            // vysledek bude ve tvaru napr.: 2 x lzice - olej
            ctecka.ZapisText(node.Attributes["mnozstvi"].Value + " x ");
            ctecka.ZapisText(node.Attributes["jednotka"].Value + " - ");
            ctecka.ZapisText(node.Attributes["nazev"].Value + "</li>");
        }
    }
    ctecka.ZapisText("</ul><br>");
    
    // nasleduje vypsani postupu vareni
    foreach(XmlNode node in receptNode) {
        if(node.Name == "postup") {
            ctecka.ZapisText("\n<div class='postup'><b>Postup:</b><br>");
            ctecka.ZapisText(node.InnerText + "</div>");
        }
    }
    ...
}
[příklad ke stažení]

Zde se nachází příklad na výše uvedené získávání elementů z XML souboru a generování kuchařky. Zde se nachází XML dokument kucharka.xml

4.3. Zapsání dat do XML souboru

Podobně, jako jsme data z XML souboru načítali pomocí XmlTextReaderu, data určená pro zápis do XML souboru budeme zapisovat s pomocí třídy XmlTextWriter. V této třídě budou pro základní práci s XML souborem užitečné zejména metody

  • XmlTextWriter.WriteStartDocument()

    Zapíše na daný výstup deklaraci XML dokumentu

  • XmlTextWriter.WriteStartElement()

    Zapíše na daný výstup element

  • XmlTextWriter.WriteAttributeString()

    Zapíše na daný výstup k elementu naposled připojenému určený atribut

  • XmlTextWriter.WriteEndElement()

    Zapíše na daný výstup koncovou značku pro tag naposledy vypsaný pomocí WriteStartElement()

Následující kód zapíše na konzolu data jako XML dokument.

[ukázka kódu]
using System.Xml;
...
  XmlTextWriter tw = new XmlTextWriter(System.Console.Out);
    
  tw.WriteStartDocument();
    tw.WriteStartElement("birthday");
    tw.WriteStartElement("day");
      tw.WriteString("22");
    tw.WriteEndElement();
    tw.WriteStartElement("month");
      tw.WriteString("12");
    tw.WriteEndElement();
    tw.WriteStartElement("year");
      tw.WriteString("1979");
    tw.WriteEndElement();
  tw.WriteEndElement();
...