Издательский дом ООО "Гейм Лэнд"СПЕЦВЫПУСК ЖУРНАЛА ХАКЕР #28, МАРТ 2003 г.

Обнаженная теория об XML.

DarkSergeant

Спецвыпуск Xakep, номер #028, стр. 028-056-5


foreach (XmlNode nameNode in nameNodes)

{

Console.WriteLine(nameNode.InnerText);

}

Данная программка выведет два имени:

Вася

Юра

Если нам надо просто «погулять» по элементам, то используются следующие фичи:

У каждого элемента есть ссылка на родительский элемент(xmlNode.ParentNode), а также список дочерних узлов (xmlNode.ChildNode). Корневой элемент документа получается через xmlNode.DocumentElement. xmlNode.Attributes – возвращает список всех атрибутов, приписанных к данному элементу.

Предыдущий пример можно было сделать и без XPath-запроса, вручную побегав по XML-дереву:

XmlDocument doc = new XmlDocument();

doc.Load("users.xml");

XmlNode usersNode = doc.DocumentElement; //получили корневой элемент

//перебираем все дочерние элементы внутри корневого элемента

foreach (XmlNode userNode in usersNode.ChildNodes)

{

if (userNode.Name != "User")

continue; //пропускаем все элементы, которые не юзеры

//перебираем все дочерние элементы внутри юзера

foreach (XmlNode roleNode in userNode.ChildNodes)

{

if (roleNode.Name != "Role")

continue; //пропускаем все, что не обязанности

//если содержимое обязанности равно "программист"-у,

//то выводим имя юзера

if (roleNode.InnerText == "программист")

Console.WriteLine(userNode["Name"].InnerText);

}

}

Как ты видишь, использование XPath-запросов здорово сокращает код и увеличивает понятность.

Но за все надо расплачиваться, за использование DOM-а мы платим увеличением времени загрузки и большим расходом памяти, так XML-файлик меньше ста килобайт может съесть памяти порядка нескольких Мегабайт.

XmlReader

Если нам хочется поэкономить память и не нужны сложные выборки данных из XML-документа, а также не страшны сложные заморочки, то можно использовать XmlReader. В отличие от DOM-а, XmlReader читает сразу не весь файл, а только по одному элементу за раз. Из-за того, что XmlReader не держит в памяти весь документ, то не возможны всякие вкусности типа XPath-запросов.

Предыдущий пример, переписанный на использование XmlReader-а, становится еще сложнее.

//создаем XmlReader, который умеет читать xml из текстового файла

XmlTextReader reader = new XmlTextReader("users.xml");

string userName = null; //имя текущего пользователя

bool isProgrammer = false; //является ли текущий пользователь программистом

string tagName = null; //название текущего элемента

//читаем по одному узлу из файла

while (reader.Read())

{

//если текущий узел - открывающий тег и название тега - юзер,

//то обнулим информацию о текущем юзере

if (reader.IsStartElement() && reader.Name == "User")

{

userName = null;

isProgrammer = false;

}

//если текущий узел - открывающий тег, то запомним имя тега на будущее

if (reader.IsStartElement())

tagName = reader.Name;

//если текущий узел - текст, то посмотрим по tagName

//какому элементу этот текст принадлежит

if (reader.NodeType == XmlNodeType.Text)

{

switch (tagName)

{

case "Role":

//если у текущего пользователя есть роль "программист", то

//запомним это

if (reader.Value == "программист")

isProgrammer = true;

break;

case "Name":

//запомним имя текущего пользователя

userName = reader.Value;

Назад на стр. 028-056-4  Содержание  Вперед на стр. 028-056-6