Na Intervalu jste si již mohli přečíst článek o zobrazování dat, zapsaných ve formátu XML pomocí technologie ASP.NET s využitím XSL. Tentokrát se podíváme přímo na problematiku práce s daty, na způsob ukládání hodnot uzlů do proměnných. Ke všem operacím využijeme jazyk C#.

Dokumenty XML lze analyzovat buď takzvaným stromovým přístupem, k čemuž nám slouží typ XmlDocument nebo můžeme vyžít čtenáře XML – třídu XmlReader, která prochází celým dokumentem v lineárním pořadí (v duchu specifikace SAX).

XmlReader

Tato třída, jak sám název napovídá, je jednoduchým čtenářem dokumentů XML. Její nevýhodou je, že nám nenabízí příliš mnoho komfortu pro práci s dokumenty XML, ovládá pouze dopřednou navigaci a nemůže ani ověřit platnost vstupního dokumentu. K odbourání druhého nedostatku nám může posloužit odvozená třída XmlValidatingReader, kterou se zde ale zabývat nebudeme.

Třída XmlReader prochází dokumentem XML v lineárním pořadí. Procházení celého dokumentu zajišťuje opakované volání metody Read() (například pomocí cyklu while). Po prvním zavolání metody Read() se XmlReader přesune na kořenový uzel a další volání pak mají za následek postupný posun čtenáře na další uzly. Ke zjištění typu aktuálního uzlu nám slouží vlastnost NodeType, která vrací hodnoty z výčtu XmlNodeType (viz tabulka):

XmlNodeType
None 0
Element 1
Attribute 2
Text 3
CDATA 4
EntityReference 5
Entity 6
ProcessingInstruction 7
Comment 8
Document 9
DocumentType 10
DocumentFragment 11
Notation 12
Whitespace 13
SignificantWhitespace 14
EndElement 15
EndEntity 16
XmlDeclaration 17

V knihovně tříd .NET Fameworku můžeme najít tři konkrétní implementace XmlReaderu: XmlTextReader (který se používá k analyzování XML z libovolného proudu textu), XmlNodeReader (slouží k analyzování XML z XmlNode) a XmlValidatingReader. XmlValidatingReader je XmlReader, který ověřuje platnost dokumentu podle DTD nebo schématu.

V drtivé většině případů stačí použít pouze XmlTextReader. Podíváme se na malý příklad načtení dokumentu XML ze souboru a jeho následný průchod:

<%@ Page Language=“C#“ %>
<%@ import Namespace=“System“ %>
<%@ import Namespace=“System.Xml“ %>
<script runat=“server“>
 public void Page_Load(object sender, EventArgs e) {
  XmlTextReader xtr = new XmlTextReader(Server.MapPath(„doc.xml“));
   // otevreni dokumentu xml string str = „“;
  while (xtr.Read()) {
   str += xtr.Name + “ “ + xtr.Value + “ „;
  }
  xtr.Close();
  Label1.Text = str;
 }
</script>
<html>
<head>
</head>
<body>
<asp:Label id=“Label1″ runat=“server“>Label</asp:Label>
</body>
</html>

Tento příklad je skutečně velmi jednoduchý. Neobsahuje žádnou prevenci proti chybám (nabízí se sáhnout po příkazu try), ani nekontroluje typ uzlů (tady by bylo možné využít příkazu switch. V následujícím výpisu uvádím pouze náznak, další typy uzlů uvádím v tabulce výše:

while (xtr.Read()) {
 switch (xtr.NodeType) {
  case XmlNodeType.Element:
   str += xtr.Name;
   break;
  case XmlNodeType.XmlDeclaration:
   str += „“;
   break;
 }
}

XmlDocument

Je vidět, že XmlReader nám nenabízí příliš mnoho. Naštěstí máme k dispozici ještě další možnost analyzování dokumentu XML. Jedná se, jak jsem již naznačil v úvodu, o stromový průchod dokumentem XML s využitím typu XmlDocument. Třída XmlDocument přistupuje k dokumentu XML podle specifikace DOM W3C. Pokud nemáte žádnou představu o tom, co vlastně DOM je, doporučuji vám článek MS XMLDOM a integrace XML do ASP.

Abychom mohli s typem XmlDocument pracovat, musíme nejdříve vytvořit jeho novou instanci:

XmlDocument xDoc = new XmlDocument();

Právě jsme si vytvořili přázdný objekt xDoc typu XmlDocument. Teď jsou na řadě data. Abychom objekt xDoc naplnili daty, můžeme použít metodu Load() (další možností je naplnit objekt pomocí XmlReaderu, ale o tom snad někdy jindy):

xDoc.Load(Server.MapPath(„doc.xml“));

Nyní máme objekt typu XmlDocument plný různých informací a můžeme se vrhnout na jejich čerpání. Opět máme několik možností, jak potřebné informace získat. Jejich využití se různí případ od případu a není v mých silách uvést zde úplně všechny způsoby.

Představme si například, že náš dokument XML představuje jakýsi adresář. Je v něm několik druhů uzlů a jedním z nich je třeba <jmeno>. V následujícím příkladu naplníme proměnnou typu pole několika prvními jmény z našeho dokumentu:

string[] arrJmena = new string[5];
// vytvorime si pole
XmlNodeList jmena = xDoc.DocumentElement.GetElementsByTagName(„jmeno“);
// obstarame seznam uzlu <jmeno>
int i;
if (jmena.Count > 4) {i=4;} else {i = jmena.Count;}
//pro jednoduchost
for (int x=0; x < i; x++)
//a projdeme a ulozime cely seznam do pole
{
 arrJmena[x] = jmena[x].InnerText;
}

Metoda GetElementsByTagName() je přetížená metoda, která akceptuje jeden nebo dva parametry (oba typu string). Pokud zadáme pouze jeden parametr (jako v našem výpisu), vyhledá všechny uzly, které mají jméno rovno řetězci našeho parametru. Druhý parametr by pak navíc vybíral uzly ještě podle jmenného prostoru.

Dalším způsobem, jak získat potřebné informace z našeho dokumentu, je použití metody SelectSingleNode(string xpath). Tato metoda vrátí hodnotu prvního uzlu, který najde podle cesty XPath zadané v parametru. Metoda je opět přetížená. Druhý parametr může, stejně jako v předcházejícím případě, představovat jmenný prostor. Příklad:

XmlNode xNode = xDoc.DocumentElement.SelectSingleNode(„descendant::jmeno“);
string jmeno = xNode.InnerText;

Myslím, že tyto dva příklady pro začátek plně postačí. Pokud vám ani jeden ze způsobů nevyhovuje, podívejte se do dokumentace .NET Frameworku, je to vcelku slušný zdroj informací. Příště se podíváme, jak data XML jednoduše změnit.

Odkazy a zdroje

Žádný příspěvek v diskuzi

Odpovědět