Poznáváme C# a Microsoft.NET 44. díl – zpracování XML pomocí DOM

Náš dnešní díl bude opět pojednávat o zpracování XML v .NET. Nyní se však seznámíme s mnohem zajímavějším přístupem ke zpracování XML dokumentů, než tomu bylo doposud pomocí tříd XMLReader nebo XMLWriter.
Poznáváme C# a Microsoft.NET 44. díl – zpracování XML pomocí DOM

Document Object Model

Během minulých dvou dílů jsme se seznámili se způsobem zpracování XML dat pomocí jednosměrných průchodů použitím implementací tříd XMLReader a XMLWriter. Tento způsob byl bezesporu zajímavý a vcelku příjemný, nicméně nám skrýval jednu z nejpodstatnějších vlastností, kterou XML dostalo při svém vzniku do vínku. Touto vlastností nemám na mysli nic jiného, než je schopnost uchovávat data ve formátu XML v hierarchické struktuře. Této vlastnosti využijeme při druhém přístupu ke zpracování XML v .NET frameworku, jež nám je k dispozici, kterým je DOM (Document Object Model), což je standard definovaný známým světovým konsorciem W3C.

V případě použití tohoto přístupu nám vznikne v paměti počítače reprezentace struktury daného XML dokumentu, na rozdíl od přístupu dříve zmiňovaného (XMLReader/XMLWriter), který byl založen necachovaných streamech. To s sebou v důsledku nese možnost jak dokument číst nebo s ním manipulovat (což je primární účel DOMu) o mnoho pohodlnějším způsobem, než jedním směrem. Je nám tedy umožněno libovolně přistupovat k libovolné části XML dokumentu. Připomeňme si náš známý ukázkový dokument, který bude dále opět použit v implementačních příkladech.

<?xml version="1.0" encoding="utf-8"?>
<zamestnanci>
<zamestnanec jmeno="Jan" prijmeni="Novak" pozice="Analytik" />
  <zamestnanec jmeno="Jiri" prijmeni="Joudek" pozice="Vyvojar" />
</zamestnanci>

Použití DOM v prostředí .NET

V případě použití DOMu je každá složka XML dokumentu představována instancí určité třídy. Základem těchto tříd je abstraktní třída XMLNode, která představuje jejich společného předka. Tak například instance třídy XMLDocument reprezentují vlastní XML dokument, XMLElement představuje element, XMLAttribute reprezentuje jeden atribut elementu, XMLDocumentType deklaraci dokumentu atd.

Třída XMLDocument obsahuje důležité metody, jejichž užitím je nám umožněno vytvořit požadovanou reprezentaci hierarchické struktury XML dokumentu v paměti a to jak např. ze souboru tak z jednoduchého řetězce. Samozřejmě je také možné pomocí instancí této třídy vykonstruovanou hierarchii z paměti někam uložit (nejčastěji do souboru). Po několika řádkách teorie již následuje první příklad, který se snaží ukázat, jak je pomocí použití DOMu vypsat všechny zaměstnance z našeho dokumentu.

/// <summary>
/// Vypise vsechny zamestance z XML pomoci DOM
/// </summary>
public static void VypisZamestnance()
{
 //vytvoreni instance dokumentu
 XmlDocument lDoc = new XmlDocument();
 //nahrani XML dokumentu ze souboru do pameti
 lDoc.Load("C:/zamestnanci.xml");
 //ziskani korenoveho elementu
 XmlNode lRoot = lDoc.DocumentElement;
 //pruchod vnorenymi uzly korenoveho elementu
 foreach(XmlNode lNode in lRoot.ChildNodes)
 {
  if (lNode.Name.Equals("zamestnanec"))
  {
   //ziskani atributu konkretniho elementu
   XmlAttributeCollection lAtts = lNode.Attributes;
   foreach(XmlAttribute lAttribute in lAtts)
   {
    //vypsani nazvu a hodnoty attributu
    Console.WriteLine("{0} - {1}", lAttribute.Name,lAttribute.Value);
   }
  }
  Console.WriteLine();
 }
}

Jak vidíte, zmiňované nahrání dokumentu do paměti se provádí pomocí metody Load, jíž v přetížené verzi, která je použita v tomto příkladu, je pouze předána cesta k souboru, který obsahuje XML data. V případě, že bychom chtěli vytvořit reprezentaci hierarchické struktury dokumentu z obyčejného řetězce, použili bychom buď jinou přetíženou verzi této metody (jedna z verzí očekává typ TextReader tudíž můžeme použít instanci typu StringReader) nebo by přišla vhod metoda LoadXML.

Získání kořenového elementu dokumentu, kterým je v případě našeho dokumentu element zamestanci použijeme instanční vlastnosti DocumentElement třídy XMLDocument. Pokud chceme získat seznam dětských (vnořených) uzlů konkrétního uzlu, využijeme k tomu vlastnost ChildNodes, která je definována již na třídě XMLNode. Tato vlastnost nám vrací seznam reprezentovaný třídou XMLNodeList, která implementuje rozhraní IEnumerable, takže seznam můžeme pohodlně proházet oblíbeným cyklem forech.

Kdybychom se chtěli ujistit, jestli nějaký uzel vůbec nějaké vnořené uzly má, můžeme tak učinit vlastností HasChildNodes. K získání seznamu atributů konkrétního elementu se používá vlastnost třídy XMLNode s názvem Attributes, jež navrací XMLAttributeCollection a ta obsahuje instance tříd XMLAttribute, reprezentující jednotlivé atributy uzlu. Díky vlastnostem této třídy zjistíme název (Name) a hodnotu (Value) konkrétního atributu.

Modifikace XML pomocí DOM

Jak jsem psal, tak je přístup pomocí DOM možný použít jak pro čtení XML dat, ale také hlavně pro jejich modifikaci. Jak na to demonstruje následující příklad.

/// <summary>
/// Prida zamestnance do XML dokumentu
/// </summary>
/// <param name="Zam">Zamestanec, ktery ma byt pridan</param>
internal static void PridejZamestnance(Zamestanec Zam)
{
 XmlDocument lDoc = new XmlDocument();
 string lPath = "C:/zamestnanci.xml";
 lDoc.Load(lPath);
 XmlNode lRoot = lDoc.DocumentElement;
 //vytvoreni elementu
 XmlElement lNewElem = lDoc.CreateElement("zamestnanec");
 //vytvoreni atributu
 XmlAttribute lJmenoAttr = lDoc.CreateAttribute("jmeno");
 XmlAttribute lPrijmeniAttr = lDoc.CreateAttribute("prijmeni");
 XmlAttribute lPoziceAttr = lDoc.CreateAttribute("pozice");
 //prirazeni hodnot atributu
 lJmenoAttr.Value = Zam.Jmeno;
 lPrijmeniAttr.Value = Zam.Prijmeni;
 lPoziceAttr.Value = Zam.Pozice;
 //pridani atributu k elementu
 lNewElem.Attributes.Append(lJmenoAttr);
 lNewElem.Attributes.Append(lPrijmeniAttr);
 lNewElem.Attributes.Append(lPoziceAttr);
 //pridani elementu do dokumentu
 lRoot.AppendChild(lNewElem);
 //ulozeni dokumentu
 lDoc.Save(lPath);
 Console.WriteLine("Zamestanec {0} {1} byl uspesne pridan",Zam.Jmeno,Zam.Prijmeni);
}

public static void PridaniZamestance()
{
 Zamestanec lZam = new Zamestanec("Michal","Racek","Vyvojar");
 PridejZamestnance(lZam);
}

Za vytváření instancí tříd, které reprezentují jednotlivé druhy uzlů v XML dokumentu je zodpovědná instance třídy XMLDocument. V příkladu můžeme vidět použití dvou vytvářecích metod, kterými jsou CreateElement pro vytvoření uzlu typu element a metoda CreateAttribute pro vytvoření atributu. Po vytvoření instancí tříd XMLAttribute jim jsou nastaveny hodnoty instanční vlastností Value a následně jsou skrze vlastnost Attributes elementu přidány do kolekce XMLAttributeColection. Nový dětský uzel se vytváří užitím metody AppendChild, která je definována na třídě XMLNode. Po přidání nového elementu, můžeme reprezentaci dokumentu nechat uložit do XML a to provedeme metodou Save.

Zdrojové kódy k uvedeným příkladů jsou k dispozici zde.

Témata článku: Software, Microsoft, Programování, Element, Doma

5 komentářů

Nejnovější komentáře

  • Pavel Polívka 24. 11. 2007 13:40:58
    Programovou oflline verzi seriálu naleznete ke stažení na...
  • Libor 9. 1. 2007 8:55:50
    V tomhle případě musíš použít buď IOException, nebo FileNotFoundException...
  • mm 28. 10. 2005 9:37:03
    Zdravim.
    Chcel som pouzit tento priklad na otvorenie xml suboru pomocou...
Určitě si přečtěte

To tu ještě nebylo. Specialisté ukázali, že zavirované mohou být i titulky SRT

To tu ještě nebylo. Specialisté ukázali, že zavirované mohou být i titulky SRT

** Stáhnete si film a titulky třeba z OpenSubtitles.org ** A osud vás za ten warez záhy potrestá ** Specialisté totiž ukázali, že i v titulcích může být schovaný virus

24.  5.  2017 | Jakub Čížek | 58

Pojďme programovat elektroniku: Postavíme si bezdotykové ovládání PC za stokorunu

Pojďme programovat elektroniku: Postavíme si bezdotykové ovládání PC za stokorunu

** Vzpomínáte na Leap Motion? ** Dnes si postavíme něco podobného za zlomek ceny ** Pohrajeme si s optickým detektorem gest

Včera | Jakub Čížek | 8

WannaCry se neměl vůbec rozšířit. Stačilo, abychom používali Windows Update

WannaCry se neměl vůbec rozšířit. Stačilo, abychom používali Windows Update

** WannaCry se masivně rozšířil kvůli zranitelnosti ve Windows ** Ta mu umožnila, aby se pokusil sám napadnout další počítače ** Jenže ta chyba už je dva měsíce opravená!

22.  5.  2017 | Jakub Čížek | 97


Aktuální číslo časopisu Computer

Bojujeme proti Fake News

Dva velké testy: fotoaparáty a NASy

Co musíte vědět o změně evropského roamingu

Radíme s výběrem základní desky