Работаем с LINQ to XML. Работа с XML в.NET-приложениях

  • 18.06.2019

Работа с XML в.NET

Информатика, кибернетика и программирование

Лекция 8. Работа с XML в.NET План 1. Классы для работы с XML .NET 2. Чтение и запись потоков данных Xml 2.1. Использование класса XmlReader 2.2. Методы чтения данных 2.3. Контроль типов данных при чтении Xmlдокумента 3. Создание XMLдокумента в Visual Studio 1. Классы для работы с XML .NET Мно

Украинкский

Лекция 8. Работа с XML в.NET

План

1. Классы для работы с XML . NET

2.1. Использование класса XmlReader

2.2. Методы чтения данных

Xml -документа

1. Классы для работы с XML . NET

Многие составляющие технологии.NET неразрывно связаны с XML. А значит, XML хорошо поддерживается со стороны Framework Class Library. В.NET поддерживаются следующие технологии:

  1. XML 1.0
  2. пространства имен XML
  3. XSD схемы
  4. выражения XPath
  5. XSL преобразования
  6. DOM Level 1 Core, DOM Level 2 Core

Среда. NET Framework не только позволяет применять XML в создаваемых приложениях, но и сама применяет его в конфигурационных файлах, документации по исходному коду и в манифесте сборки.

Пример 1. Манифест сборки

Классы для работы с XML собраны в пространстве имен System . Xml . Это пространство загружается вместе с классами, которые могут использоваться для обработки данных XML .

Таблица 1. Основные классы чтения и записи данных XML

XmlReader

Абстрактный класс, выполняющий чтение и обеспечивающий быструю доставку некешированных данных XML . Класс представляет собой однонаправленный синтаксический анализатор

XmlWriter

Абстрактный класс, выполняющий запись данных в виде потока или файла

XmlTextReader

Расширяет возможности класса XmlReader . Обеспечивает однонаправленный потоковый доступ к данным XML

XmlTextWtiter

Расширяет возможности класса Xml . Writer XML

Таблица 2. Некоторые классы обработки данных XML

XmlNode

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

XmlDocument

Расширяет класс XmlNode . Представляет собой реализацию DOM от W 3 C . Обеспечивает древовидное представление XML -документа в памяти с возможностями навигации и редактирования

XmlNavigator

Обеспечивает навигацию по документу

XMLDataDocument

служит мостом между хранилищами данных и реляционными данными, хранящимися в DataSet

2. Чтение и запись потоков данных Xml

Среда. NET Framework поддерживает два способа обработки XML -документов: потоковый ввод-вывод и DOM . Абстрактные классы XmlReader , XmlWriter и порожденные от них классы поддерживают потоковую модель ввода-вывода.

Классы, основанные на XmlReader обеспечивают быстрый однонаправленный курсор , который организует поток данных XML для обработки.

От XmlReader порождены следующие классы:

От XmlWriter порождены следующие классы:

XmlTextWriter

Расширяет возможности класса Xml . Writer . Обеспечивает быструю однонаправленную генерацию потоков XML

XmlQueryOutput

Расширяет возможности класса Xml . Writer , О беспечива ет функциональность, необходимую для вывода результатов преобразований XSLT.

Для работы с данными каждый из классов предоставляет необходимые методы.

2.1. Использование класса XmlReader

Пример чтения данных XML из файла. Данные хранятся в файле "book2.xml" и представляют собой описание книжного каталога:

Страны Мира

Книжний Клуб

Харьков

380

$4.00

Секреты работы в Windows

Дэвид Маккормик

Харьков

300

$5.20

Выбор и модернизация компьютера

Михаил Кутузов

Питер - Москва

320

$6.30

3d max

Кэлли Мердок

Киев - Москва

1050

$10.95

Система <span>Программирования </span> Delphi

Волков Андрей

Москва

800

$10.95

Как собрать свой компьютер

Джон Косли

Москва

300

$6.90

dfsdfdfsdf

sdfsdf

фіваваіва

234

$12.8

Создадим форму с двумя кнопками и текстовым редактором (richTextBox1), в который будем размещать прочитанные данные.

При нажатии кнопки ReadXml выполняется чтение и разбор XML -файла и вывод его в текстовый редактор. Обработчик кнопки ReadXML_Click :

private void ReadXML_Click(object sender, EventArgs e)

//чтение файла

RichTextBox1.Clear(); //очистка редактора

XmlReader rdr = XmlReader .Create("book2.xml" );//создание объекта rdr

while (rdr.Read())

if (rdr.NodeType == XmlNodeType .Text)

RichTextBox1.AppendText(rdr.Value + "\r\n" );

Класс XmlReader является абстрактным, т.есть, для таких классов нельзя создавать объекты оператором new . Для того, чтобы его можно было использовать, нужно включить в него статические методы.

В этом обработчике используется статический метод Create , который возвращает объект XmlReader . Дальше в цикле while выполняется чтение каждой строки файла. По мере чтения производится проверка свойства NodeType . Если узел является текстовым, в текстовый редактор добавляется его содержимое.

2.2. Методы чтения данных

Классы для работы с XML предоставляют несколько способов передвижения по XML -документу. Например, метод Read() перемещает на следующий узел. Потом можно проверить, имеет ли этот узел содержимое (HasValue ()) или атрибуты (YasAttributes ()).

Основные методы анализа документа представлены в таблице ниже.

Read()

читает очередную запись и перемещает на следующий узел

HasValue ()

возвращает true false – противном случае

HasAttributes ()

просматривает элемент на наличие атрибутов. Возвращает true , если элемент имеет содержимое, false – противном случае

ReadStartElement()

проверяет, является ли узел корневым, после чего смещается на следующий узел. Если узел не корневой, возбуждается исключение XmlException.

IsStartElement()

аналогичен методу ReadStartElement()

ReadString()

чтение одной строки из файла, содержащего документ

ReadElementString()

подобен методу ReadString () за исключением того, что ему можно передать имя элемента. Если следующий узел с содержимым не является начальным дескриптором или если параметр Name не совпадает с текущим параметром узла, возбуждается исключение

MoveToContent()

перемещение к содержимому узла

Пример 2. Вывод отдельных элементов XML -документа

Рассмотрим применения метода ReadElementString () и других методов, а также применение файловых потоков (чтения из файла).

Не забыть подключить using System.IO;

Добавим на форму кнопку Read from file . Код обработчика будет следующим:

private void btmReadXml2_Click(object sender, EventArgs e)

//чтение только название книг (элемент "TITLE"

RichTextBox1.Clear();

FileStream fs = new FileStream ("book2.xml" , FileMode .Open);

XmlReader rdr = XmlReader .Create(fs);

while (!rdr.EOF)

//Если попадаем на тип элемента, проверить его и загрузить в окно

RichTextBox1.AppendText(rdr.ReadElementString() + "\r\n" );

else

// в противном случае - переместиться на след.запись

Rdr.Read();

В этом примере в цикле while используется метод MoveToContent() для поиска узла типа XmlNodeType . Element с названием книги rdr.Name == "TITLE" )

if (rdr.MoveToContent() == XmlNodeType .Element && rdr.Name == "TITLE" )

Просмотр выполняется до конца файла (условие цикла

while (!rdr.EOF)

Если типом узла не является элемент или его имя не совпадает с "TITLE " , то вызывается метод Read () для перехода к следующему узлу. Если очередной узел "TITLE " найден, его содержимое добавляется в окно вывода. Таким образом, будут выведены только названия книг.

2.3. Контроль типов данных при чтении Xml -документа

Класс XmlReader также позволяет считывать данные со строгим контролем типов. Для этого используются методы ReadElementContentAs ... ReadElementContentAsDouble (), ReadElementContentAsBoolean () и другие. Далее показано как можно считывать значение в десятичном формате и выполнять вычисления. В примере выбирается значение цены книги, которое увеличивается на 25%.

Создадим еще одну кнопку с надписью New Price , а в ее обработчике напишем код:

private void btnNewPrice_Click(object sender, EventArgs e)

//Обработчик кнопки NewPrice - контроль типов

RichTextBox1.Clear();

XmlReader rdr = XmlReader .Create("book2.xml" );

while (rdr.Read())

if (rdr.NodeType == XmlNodeType .Element)

if (rdr.Name == "PRICE" )

decimal price = rdr.ReadElementContentAsDecimal();

RichTextBox1.AppendText("Curent Price = " + price+ "\r\n" );

Price += price * (decimal )0.25;

RichTextBox1.AppendText("New Price = " + price + "\r\n\r\n" );

else if (rdr.Name== "TITLE" )

RichTextBox1.AppendText(rdr.ReadElementContentAsString()+ "\r\n" );

rdr.Close();

Если это значение не может быть преобразовано к требуемому типу, возбуждается исключение FormatException .

Компилируем и запускаем на выполнение наш проект.

В результате получаем сообщение об ошибке. Причина – текст элемента имеет вид:

< PRICE >$10.95

Исправим все элементы < PRICE > 10.95,

а документ сохраним под именем ("book 3 .xml" );

В результате получим:

3. Создание XML -документа в Visual Studio

Для создания XML -файла в среде Visual Studio нужно в меню File выбрать New -> File . В окне создания выбрать Xml -файл

Откроется Xml -редактор, в котором можно вводить элементы Xml . Редактор автоматически проверяет ошибки и подставляет закрывающие теги. Созданный файл можно сохранить в нужном месте на диске командой SaveXmlFile . xml As ...


А также другие работы, которые могут Вас заинтересовать

25682. Тонкая кишка 57.5 KB
Клетки кишечного эпителия у 4недельного эмбриона не дифференцированы и характеризуются высокой пролиферативной активностью. В это время среди эндокриноцитов преобладают переходные клетки с недифференцированными гранулами выявляются ЕСклетки Gклетки и Sклетки. В плодном периоде преобладают ЕСклетки большинство из которых не сообщается с просветом крипт закрытый тип; в более позднем плодном периоде появляется открытый тип клеток. Крипты содержат камбиальные элементы эпителия и дифференцирующиеся из них клетки.
25683. солевом обмене веществ. 44.5 KB
Кроме того эти ткани принимают участие в водносолевом обмене веществ. Хрящевые ткани входят в состав органов дыхательной системы суставов межпозвоночных дисков и др. В свежей хрящевой ткани содержится около 7080 воды 1015 органических веществ и 47 солей.
25684. Эмбриогенез 239.5 KB
Вместе с тем появляются особенности отличающие развитие человека от развития других представителей позвоночных. Процесс внутриутробного развития зародыша человека продолжается в среднем 280сут 10 лунных месяцев. Эмбриональное развитие человека принято делить на 3 периода: начальный 1я неделя зародышевый 2 8я неделя плодный с 9й недели развития до рождения ребенка.
25685. Эпителиальные ткани. Поверхностные эпителии 36 KB
Питание эпителиоцитов осуществляется диффузно через базальную мембрану со стороны подлежащей соединительной ткани с которой эпителий находится в тесном взаимодействии. В соответствии с формой клеток составляющих однослойный эпителий последние подразделяются на плоские сквамозные кубические и призматические столбчатые. 1Однослойный эпителий может быть однорядным и многорядным. Такой эпителий называют еще изоморфным.
25686. Яички 60 KB
В постнатальном периоде в семенных канальцах гоноциты размножаются а эпителий половых шнуров сохраняется в качестве поддерживающих клеток. Базальный слой внутренний волокнистый слой расположенный между двумя базальными мембранами сперматогенного эпителия и миоидных клеток состоит из сети коллагеновых волокон. Непосредственно к миоидному слою примыкает неклеточный слой образованный базальной мембраной миоидных клеток и коллагеновыми волокнами. За ними расположен слой состоящий из фибробластоподобных клеток прилежащий к базальной...
25687. Яичники 58.5 KB
Около половины овогоний с 3го месяца развития начинает дифференцироваться в овоцит первого порядка период малого роста находящийся в профазе мейоза. К моменту рождения число овогоний прогрессивно уменьшается и составляет около 45 большая часть клеток подвергается атрезии основные клетки представляют собой вступившие в период роста овоциты 1го порядка. 2 стадия период роста протекает в функционирующем яичнике и состоит в превращении овоцита 1го порядка первичного фолликула в овоцит 1го порядка в зрелом фолликуле. 3 стадия...
25688. Мужские половые клетки 40 KB
Скорость их движения у человека 3050мкм с Целенаправленному движению способствуют хемотаксис движение к химическому раздражителю или от него и реотаксис движение против тока жидкости. Мужские половые клетки человека сперматозоиды или спермии длиной 70мкм имеют головку и хвост. В ядре сперматозоида человека содержится 23 хромосомы одна из которых является половой X или У остальные аутосомами.
25689. Понятие о системе крови. Эритроциты 47 KB
Система крови включает в себя кровь органы кроветворения красный костный мозг тимус селезенку лимфатические узлы лимфоидную ткань некроветворных органов. Элементы системы крови имеют общее происхождение из мезенхимы и структурнофункциональные особенности подчиняются общим законам нейрогуморальной регуляции объединены тесным взаимодействием всех звеньев. Так постоянный состав периферической крови поддерживается сбалансированными процессами новообразования гемопоэза и разрушения клеток крови.
25690. МОЧЕВЫДЕЛИТЕЛЬНАЯ СИСТЕМА 41 KB
Длина его канальцев до 50мм а всех нефронов в среднем около 100 км. Остальные 15 нефронов располагаются в почке так что их почечные тельца извитые проксимальные и дистальные отделы лежат в корковом веществе на границе с мозговым веществом. Таким образом корковое и мозговое вещества почек образованы различными отделами трех разновидностей нефронов. Корковое вещество составляют почечные тельца извитые проксимальные и дистальные канальцы всех типов нефронов.

Язык - не сын, а отец мысли.
Оскар Уайльд

Аббревиатура XML расшифровывается как Extensible Markup Language, в переводе «расширяемый язык разметки». Как и язык HTML, он является подмножеством SGML (Standard General Markup Language) - «дедушки» языков разметки. Мы уже не раз сталкивались с форматом XML. Таков формат конфигурационных файлов, файла описания объектных источников данных.

XML - это универсальный, независящий от платформы стандарт описания информациии, который можно использовать для представления иерархических данных и унификации передаваемой информации. Без его знания невозможно понимание SOAP и следовательно, веб-сервисов. XML стал де-факто стандартом передачи данных в сети Интернет. Стандарт XML и связанных с ним форматов определяется консорциумом W3C(World Wide Web Consortium). Например, мы создаем aspx страницы в формате XHTML - переходном между HTML и XML, стандарт которого тоже определен W3C. Стандарт XHTML налагает более строгие правила на правильное формирование документа, аналогичные правилам XML.

Давайте поймем главное отличие XML от HTML. XML создан для описания данных и фокусируется на том, что именно они из себя представляют. HTML создан для демонстрации данных и фокусируется на том, как данные выглядят. Если в традиционном HTML понятия «представление» и «визуализация» часто смешиваются, то при работе с XML мы четко разделяем эти понятия. Теги XML не предопределены создателями языка, в отличие от тегов HTML. Каждый автор документа сам определяет собственные теги.

Стандарт требует, чтобы программа, которая обрабатывает XML-документ, должна остановить работу, если обнаружила ошибку. А если браузер обнаружит непонятный тег в HTML, или отсутствие закрывающего тега, он это просто игнорирует.

В начале XML-документа обязательно появляется его декларация, или пролог. В нем указывается версия стандарта XML, которому он соответствует.

является ошибкой в XML.

У тегов могут быть атрибуты. Значения атрибутов должны быть заключены в кавычки. Порядок атрибутов значения не имеет. Между открывающим и закрывающими тегами может находится текст. В XML сохраняются все пробелы, находящиеся в тексте. Если текста нет, можно применить сокращенную форму записи. Пример тега XML:

Это краткая форма тега

Вам это ничего не напоминает? Правила описания элементов ASP.NET точно такие же.

Существует атрибут xmlns, который определяет пространство имен. Значением его может быть любое уникальное имя. Существует договоренность использовать URL, так как они уникальны. Пространства имен имеют смысл, аналогичный их применению в.NET Framework - чтобы не смешивать одинаковые имена, используемые разными разработчиками. Название пространства имен отделяется от имени двоеточием.

XML-файлы представляют иерархическую информацию, которую можно представить в виде дерева с одним корнем.

Документы XML, удовлетворяющие всем требованиям синтаксиса, называют правильными (well-formed). Для описания данных XML использует DTD (Document Type Definition) - определение типа документа. Если файл соответствует DTD, он считается действительным (valid) .

Браузеры IE 6.0, FireFox 1.5 отображают XML-файлы с выделением синтаксиса. Родительские узлы можно раскрывать и закрывать. Например, в закрытом виде корневой узел файла BirthDay.xml выглядит так:

Среды разработки Visual Studio и VWD Express проверяют правильность xml-документов прямо во время редактирования.

AdRotator

Элемент управления AdRotator позволяет показывать рекламные баннеры и автоматически заменять их на другие. Сами баннеры описаны в файле XML или другом источнике данных. Реклама обновляется каждый раз при обновлении страницы. В свойстве AdvertismentFile задается имя XML-файла. Скелет XML-файла таков.

Внутри узла Advertisements располагаются узлы

У этих узлов имеются 5 атрибутов, все они необязательны.

Пример файла AdvertismentFile, он называется ads.xml.

fixed.gif http://www.im.am Бесплатный хостинг 40 хостинг logo2.jpg http://www.nv.am Газета "Новое время" 50 новости summer.jpg http://www.utro.ru Певицу Жасмин избил муж! 100 желтые новости

На страницу помещен элемент управления. Его свойство AdvertisementFile указывает на этот файл.

Если установлено свойство Keyword, то элемент управления показывает только ту рекламу, которая соответствует его содержанию. Так как его можно менять динамически, можно подстраивать рекламу под нужды пользователя. Keyword должен встречаться хотя бы раз в файле объявлений, иначе вместо рекламы будет пустой прямоугольник.

В предыдущих версиях ASP.NET можно было работать только с файлами XML. Теперь можно использовать любой источник данных, связавшись с элементом управления-источником данных. В таком случае необходимо указать как минимум 3 поля источника в свойствах ImageUrlField, NavigateUrlField и AlternateTextField.

Файлы преобразования документа

Известно, что для форматирования HTML-файлов часто используются CSS (Cascading Stylesheets), хотя это необязательно, так как браузеры соотносят со всеми тегами определенный внешний вид. Элемент

Задает параграф, - полужирный шрифт - браузер знает, как их показывать.

Поскольку XML не использует изначально заданные теги, их значение может быть каким угодно:

может означать таблицу HTML, а может и деревянный стол. Поэтому браузеры показывают XML-документы «как есть». Можно задать CSS файлы и для XML-документов, но это не рекомендуется.

Для того, чтобы задать формат отображения XML-документов, используются таблицы стилей XSL . XSL - расширяемый язык стилей (Extensible Stylesheet Language) гораздо более богат возможностями, чем CSS. XSL - больше, чем просто таблица стилей.

Один и тот же файл XML можно связать с разными таблицами XSL, в том числе программно.

XSL состоит из 3 частей:

  1. XSLT - метода преобразования XML-документов
  2. XPath - метода задания частей и путей к элементам XML
  3. XSL Formatting Objects - метода форматирования XML-документов

Самая важная часть XSL - это язык преобразований XSLT (XSL Transformation). Он применяется для преобразования XSL-документов в другие типы документов или другие XSL -документы. Часто XSLT используется для преобразования XSL-документа в формат HTML.

Для того, чтобы создать XSLT-документ, выберите в диалоге создания файла XSLT file. VS 2005 создает каркас таблицы стилей. Так как таблица стилей сама по себе является XML-документом, она начинается с декларации XML.

Если вы изучали CSS, то знаете, что для задания стилей используются правила. Правило состоит из селектора и описания стиля в фигурных скобках.

В этот тег вложен шаблон HTML -файла. Комментарий напоминает о том, что туда нужно вставить XSL-элементы.

Создание файлов XSLT рассмотрим на примере. Создайте в папке App_Data файл XML "Quotes.xml"

Хотели как лучше, а получилось как всегда. Виктор Черномырдин Америка - континент, названный так потому, что его открыл Колумб. Жорж Элгози Я прихожу в бешенство от одной мысли о том, сколько бы я всего узнал, если бы не ходил в школу. Джордж Бернард Шоу Многое придумано для того, чтобы не думать. Карел Чапек Если скажешь правду, все равно рано или позно попадешься. Оскар Уайльд Быть ему президентом, если его до той поры не повесят. Марк Твен

Чтобы внести в выходной поток XSLT-преобразования каждый XML-элемент, применяется тег XSL xsl:for-each. Элемент:for-each определяет местоположение элементов в XML-документе и повторяет шаблон для каждого из них.

Данные можно отсортировать с помощью тега xsl:sort, который должен находиться внутри элемента xsl:for-each:

Окончательный вид файла трансформации:

Известные цитаты

Цитата Автор

Если хотите увидеть результат преобразования документа в браузере, включите после XML-декларации объявление

,

или выберите в меню XML пункт Show XML Output и определите файл преобразования.

Тот же самый XML-документ можно преобразовать с помощью другого XSL-файла:

Мастера Афоризма



В результате будет выводиться цитаты, разделенные горизонтальной линией.

Файлы определения схемы документа

Согласно современному стандарту, валидный документ должен соответствовать связанному с ним файлу XSD (XML Schema Definition) - файлу определения схемы XML, который определяет конкретный язык, то есть описывает, какие элементы и типы могут появляться в документе. Схемы XSD призваны заменить DTD (Document Type Definition), разница между ними заключается в том, что файлы XSD сами тоже используют синтаксис XML. Схемы XSD позволяют определить, какие теги разрешены, обязательны они или нет, могут ли повторяться в документе и так далее. Таким образом, XML описывает данные, а XSD - структуру этих данных, или метаданные. В терминах программирования, XSD - описание типов, в то время как в XML-файле описаны объекты этих типов. По адресу http://www.w3.org/TR/2003/WD-xmlschema-11-req-20030121/ находится рабочий проект стандарта XSD 1.1.

Файл описания схемы начинается с описания префикса пространства имен, который включается затем во все элементы этого файла. Адрес http://tempuri.org предназначается для задания URI для пространств имен ASP.NET .

Например, это определение задает, что элемент "Author" строкового типа, должен появляться один и только один и раз, и если он не указан, то принимает значение "Пушкин".

Параметр maxOccurs="unbounded" указывает, что элемент может встречаться любое количество раз.

Параметр ref позволяет ссылаться на уже описанный в данном файле глобальный элемент или атрибут, чтобы избежать повторного описания одних и тех же элементов.

  1. определить простые и сложные типы.

В XSD есть предопределенные типы - примерно такие же, как в.NET. Во время работы приложения они преобразуются в типы.NET. На их основании можно строить сложные типы, похожие на структуры языков программирования. Сложный тип состоит из последовательности описаний элементов. Определим сложный тип

Тег определяет, что элементы в данном типе должны появляться в заданном порядке. Если бы использовался тег , то элементы могли бы появляться в любом порядке.

Тег похож на структуру с вариантами. Он определяет, что в элементе данног типа должен быть только один из вложенных элементов.

В следующем примере определен простой тип, вложенный в определение элемента MyValue.

  1. Добавлять новые группы и группы атрибутов.

В определении сложного типа могут фигурировать атрибуты. Предположим, мы хотим построить схему такого файла:

Атрибуты могут быть только простых типов.

  1. Добавлять аннотации.

Аннотации позволяют вставлять описание существующих элементов, таким образом в файл добавляется документация.

Цитаты разных авторов

предназначается для читателей файла, а для обрабатывающих файл программ.

Редактировать XSD-файлы в Visual Studio 2005 можно и через исходный код, и с помощью дизайнера. Для XML-документа можно автоматически сгенерировать соответсвующую ему схему. В окне свойств XML-документа можно задать как файл схемы, так и файл преобразования. В таком случае студия автоматически проверяет файл на соответствие схеме, и даже IntelliSense подставляет теги из этого файла.

Класс XmlReader

С помощью класса XmlReader можно быстрее, чем другими методами, получить данные из XML-документов.

XmlReader - это абстрактный класс. Чтобы начать чтение, в статический метод Create передается объект класса XmlReaderSettings. Эта функция подсчитывает число узлов в документе.

using System.Xml; using System.IO; private int CountNodes(string xmlFile) { int NodesCount=0; XmlReaderSettings settings = new XmlReaderSettings(); settings.IgnoreWhitespace = true; settings.IgnoreComments = true; using (XmlReader reader = XmlReader.Create(xmlFile, settings)) { while (reader.Read()) { if (reader.NodeType == XmlNodeType.Element) { NodesCount++; } } } return NodesCount; }

Класс XmlReader позволяет извлекать из документа классы CLR. Пусть у нас есть меню ресторана.

Напишем функцию, которая посчитает сумму цен и количества калорий в меню.

protected void Page_Load(object sender, EventArgs e) { int ItemsCount = 0; decimal DishesTotal = 0; UInt16 CaloriesTotal = 0; XmlReaderSettings settings = new XmlReaderSettings(); settings.IgnoreWhitespace = true; NameTable nt = new NameTable(); object food = nt.Add("food"); object price = nt.Add("price"); object calories = nt.Add("calories"); settings.NameTable = nt; string MenuFile = Path.Combine(Request.PhysicalApplicationPath, "menu.xml"); using (XmlReader reader = XmlReader.Create(MenuFile, settings)) { while (reader.Read()) { if (reader.NodeType == XmlNodeType.Element && food.Equals(reader.LocalName)) { ItemsCount++; } if (reader.NodeType == XmlNodeType.Element && price.Equals(reader.LocalName)) { DishesTotal += (UInt16)reader.ReadElementContentAsDecimal(); } if (reader.NodeType == XmlNodeType.Element && calories.Equals(reader.LocalName)) { CaloriesTotal += (UInt16)reader.ReadElementContentAsInt(); } } } Response.Write(String.Format("Вы заказали {0} блюда на сумму {1:C}, {2} калорий", ItemsCount, DishesTotal, CaloriesTotal)); }

Класс XPathDocument

Класс обеспечивает чтение и хранение в памяти XML-документов для трансформаций с помощью XSL. По документу можно перемещаться в любом направлении и получать произвольный доступ к любому элементу, используя выражения XPath.

Возьмем XML-документ "Quotes.xml"и файл трансформации XSL "Quotes.xsl". В выходной поток страницы будет направлен результат преобразования XML-документа.

<% XPathDocument doc = new XPathDocument(Server.MapPath("App_Data\\Quotes.xml")); XslCompiledTransform xsl = new XslCompiledTransform(); xsl.Load(Server.MapPath("App_Data\\Quotes.xsl")); xsl.Transform(doc, null, Response.OutputStream); %>

Благодаря тому, что в файле трансформации определены табличные теги, на странице появится таблица с нужной информацией.

Элемент управления XML

Элемент управления XML предоставляет способ преобразовать XML-документ, используя таблицу стилей XSL. Свойство DocumentSource позволяют задать XML-файл, в котором находятся данные, TransformSource - файл трансформации XSLT.

В предыдущем примере того же результата можно достичь, если поставить на странице элемент управления XML.

XMLDataSource

Элемент -источник данных XMLDataSource обеспечивает простой способ подключения XML-документов как источников данных к элементам, отображающим информацию. Также можно задать запрос XPath для того, чтобы отфильтровать данные. Как и SqlDataSource, он позволяет редактировать, удалять, добавлять записи данных. Для этого нужно получить доступ к находящемуся в нем объекту XmlDataDocument с помощью вызова метода GetXmlDocument. После редактирования документ сохраняется с помощью метода Save.

В отличие от табличных данных в СУБД, данные в XML-файлах иерархичны, поэтому XMLDataSource удобно привязывать к иерархичным элементам управления, например Menu.

Синтаксис привязки к данным XML

Так как в приложениях XML-данные используются все чаще и чаще, был введен метод привязки данных, полученных из XMLDataSource.

Эти методы работают так же, как Bind и Eval, которые обсуждались в 7 лекции.

Применим этот синтаксис в элементе DataList, который получает данные из источника данных XmlDataSource:

Заключение

В этой лекции мы рассмотрели работу с данными типа XML. XML предоставляет универсальный способ для описания и обмена структурированной информацией, независимо от приложений и разработчиков. На этом завершили рассмотрение работы с источниками данных.

В первой статье в блоге .NET «Работаем с XML » в комментариях народ потребовал статьи LINQ to XML. Что же, попробуем раскрыть принципы работы этой новой технологии от Microsoft.

Создадим базу для ведения каталога аудиозаписей. База будет состоять из треков:

  • Название
  • Исполнитель
  • Альбом
  • Продолжительность
Мы научимся добавлять, редактировать, удалять и делать различные выборки из нашей базы.

Для начала создадим консольное приложение (я пишу свои проекты на C#, но суть в общем-то понятна будет всем) и подключим необходимое пространство имен

Using System.Xml.Linq;

Создание файлов XML

Создадим XML файл нашей базы содержащий несколько тестовых записей уже при помощи LINQ:

//задаем путь к нашему рабочему файлу XML string fileName = "base.xml"; //счетчик для номера композиции int trackId = 1; //Создание вложенными конструкторами. XDocument doc = new XDocument(new XElement("library", new XElement("track", new XAttribute("id", trackId++), new XAttribute("genre", "Rap"), new XAttribute("time", "3:24"), new XElement("name", "Who We Be RMX (feat. 2Pac)"), new XElement("artist", "DMX"), new XElement("album", "")), new XElement("track", new XAttribute("id", trackId++), new XAttribute("genre", "Rap"), new XAttribute("time", "5:06"), new XElement("name", "Angel (ft. Regina Bell)"), new XElement("artist", "DMX"), new XElement("album", "...And Then There Was X")), new XElement("track", new XAttribute("id", trackId++), new XAttribute("genre", "Break Beat"), new XAttribute("time", "6:16"), new XElement("name", "Dreaming Your Dreams"), new XElement("artist", "Hybrid"), new XElement("album", "Wide Angle")), new XElement("track", new XAttribute("id", trackId++), new XAttribute("genre", "Break Beat"), new XAttribute("time", "9:38"), new XElement("name", "Finished Symphony"), new XElement("artist", "Hybrid"), new XElement("album", "Wide Angle")))); //сохраняем наш документ doc.Save(fileName);

Теперь в папке с нашей программой после запуска появится XML файл следующего содержания:
Who We Be RMX (feat. 2Pac) DMX The Dogz Mixtape: Who"s Next?! Angel (ft. Regina Bell) DMX ...And Then There Was X Dreaming Your Dreams Hybrid Wide Angle Finished Symphony Hybrid Wide Angle

Для создания подобного файла средствами XmlDocument кода понадобилось где-то раза в 2 больше. В коде выше мы воспользовались конструктором класса XDocument, который принимает в качестве параметра перечень дочерних элементов, которыми мы изначально хотим инициализировать документ. Используемый конструктор XElement принимает в качестве параметра имя элемента, который мы создаем, а так же перечень инициализирующих элементов. Удобно то, что мы в этих элементах можем задавать как новые XElement, так и XAttribute. Последние отрендретятся в наш файл как атрибуты самостоятельно. Если вам не нравится использоваться такую вложенность конструкторов и вы считаете такой код громоздким, то можно переписать в более традиционный вариант. Код ниже даст на выходе аналогичный XML файл:

XDocument doc = new XDocument(); XElement library = new XElement("library"); doc.Add(library); //создаем элемент "track" XElement track = new XElement("track"); //добавляем необходимые атрибуты track.Add(new XAttribute("id", 1)); track.Add(new XAttribute("genre", "Rap")); track.Add(new XAttribute("time", "3:24")); //создаем элемент "name" XElement name = new XElement("name"); name.Value = "Who We Be RMX (feat. 2Pac)"; track.Add(name); //создаем элемент "artist" XElement artist = new XElement("artist"); artist.Value = "DMX"; track.Add(artist); //Для разнообразия распарсим элемент "album" string albumData = "The Dogz Mixtape: Who"s Next?!"; XElement album = XElement.Parse(albumData); track.Add(album); doc.Root.Add(track); /* *остальные элементы добавляем по аналогии */ //сохраняем наш документ doc.Save(fileName);

Естественно выбирать необходимый способ нужно по ситуации.

Чтение данных из файла

//задаем путь к нашему рабочему файлу XML string fileName = "base.xml"; //читаем данные из файла XDocument doc = XDocument.Load(fileName); //проходим по каждому элементу в найшей library //(этот элемент сразу доступен через свойство doc.Root) foreach (XElement el in doc.Root.Elements()) { //Выводим имя элемента и значение аттрибута id Console.WriteLine("{0} {1}", el.Name, el.Attribute("id").Value); Console.WriteLine(" Attributes:"); //выводим в цикле все аттрибуты, заодно смотрим как они себя преобразуют в строку foreach (XAttribute attr in el.Attributes()) Console.WriteLine(" {0}", attr); Console.WriteLine(" Elements:"); //выводим в цикле названия всех дочерних элементов и их значения foreach (XElement element in el.Elements()) Console.WriteLine(" {0}: {1}", element.Name, element.Value); }

Здесь в коде, думаю, ничего сложного нету и приведены комментарии. После запуска нашей программый в консоли отобразится следующий результат:

Track 1 Attributes: id="1" genre="Rap" time="3:24" Elements: name: Who We Be RMX (feat. 2Pac) artist: DMX album: The Dogz Mixtape: Who"s Next?! track 2 Attributes: id="2" genre="Rap" time="5:06" Elements: name: Angel (ft. Regina Bell) artist: DMX album: ...And Then There Was X track 3 Attributes: id="3" genre="Break Beat" time="6:16" Elements: name: Dreaming Your Dreams artist: Hybrid album: Wide Angle track 4 Attributes: id="4" genre="Break Beat" time="9:38" Elements: name: Finished Symphony artist: Hybrid album: Wide Angle

Изменение данных

Попробуем пройтись по всем узлам library и увеличить аттрибут Id элемента track на 1.
(дальше писать объявление пути к файлу и результат вывода в консоль я приводить не буду, чтобы не перегружать лишней информацией статью, все компилировал, все работает:)) :

//Получаем первый дочерний узел из library XNode node = doc.Root.FirstNode; while (node != null) { //проверяем, что текущий узел - это элемент if (node.NodeType == System.Xml.XmlNodeType.Element) { XElement el = (XElement)node; //получаем значение аттрибута id и преобразуем его в Int32 int id = Int32.Parse(el.Attribute("id").Value); //увеличиваем счетчик на единицу и присваиваем значение обратно id++; el.Attribute("id").Value = id.ToString(); } //переходим к следующему узлу node = node.NextNode; } doc.Save(fileName);

Теперь попробуем это сделать более правильным способом для наших задач:

Foreach (XElement el in doc.Root.Elements("track")) { int id = Int32.Parse(el.Attribute("id").Value); el.SetAttributeValue("id", --id); } doc.Save(fileName);

Как видим – этот способ нам подошел больше.

Добавление новой записи

Добавим новый трек в нашу библиотеку, а заодно вычислим средствами LINQ следующий уникальный Id для трека:

Int maxId = doc.Root.Elements("track").Max(t => Int32.Parse(t.Attribute("id").Value)); XElement track = new XElement("track", new XAttribute("id", ++maxId), new XAttribute("genre", "Break Beat"), new XAttribute("time", "5:35"), new XElement("name", "Higher Than A Skyscraper"), new XElement("artist", "Hybrid"), new XElement("album", "Morning Sci-Fi")); doc.Root.Add(track); doc.Save(fileName);

Вот таким подним запросом ко всем элементам вычисляется максимальное значение аттрибута id у треков. При добавлении полученное максимальное значение инкрементируем. Само же добавление элемента сводится к вызову метода Add. Обратите внимание, что добавляем элементы в Root, так как иначе нарушим структуру XML документа, объявив там 2 корневых элемента. Так же не забывайте сохранять ваш документ на диск, так как до момента сохранения никакие изменения в нашем XDocument не отразятся в XML файле.

Удаление элементов

Попробуем удалить все элементы исполнителя DMX:

IEnumerable tracks = doc.Root.Descendants("track").Where(t => t.Element("artist").Value == "DMX").ToList(); foreach (XElement t in tracks) t.Remove();

В этом примере мы вначале выбрали все треки у который дочерний элемент artst удовлетворяет критерии, а потом в цикле удалили эти элементы. Важен вызов в конце выборки ToList(). Этим самым мы фиксируем в отдельном участке памяти все элементы, которые хотим удалить. Если же мы надумаем удалять из набора записей, по которому проходим непосредственно в цикле, мы получим удаление первого элемента и последующий NullReferenceException. Так что важно помнить об этом.
По совету xaoccps удалять можно и более простым способом:
IEnumerable tracks = doc.Root.Descendants("track").Where(t => t.Element("artist").Value == "DMX"); tracks.Remove();
В этом случае приводить к списку наш полученный результат вызовом функции ToList() не нужно. Почему этот способ не использовал изначально описал в

Уже довольно много времени прошло с тех пор, как я пообещал рассказать о работе с данными в формате XML при разработке.NET-приложений. Обещания надо выполнять. Прошу только учесть, что эта статья ориентирована не на профессиональных.NET-разработчиков, а на тех, кто ещё не имеет существенного опыта создания.NET-приложений.


Зачем нам работать с XML?

Если вы ещё не очень хорошо представляете себе, что такое XML, то рекомендую прочитать статью "XML - это всерьёз и надолго" в "КВ" № за 2007-й год. Чтобы сэкономить место для более важных вещей, здесь сам формат XML разбираться не будет.

Перед тем, как начинать знакомиться с программным кодом, нужно ответить на один принципиальный вопрос: зачем вообще включать поддержку XML в своё приложение? Думаю, что многие задавали себе этот вопрос относительно многих технологий, и не все после ответа были включены в приложения. Впрочем, с XML дело обстоит несколько иначе, и существуют реальные поводы использовать этот формат во многих ситуациях.

Главное преимущество XML в том, что, будучи по природе текстовым форматом, он, тем не менее, прекрасно позволяет хранить и передавать любые данные. Поскольку этот формат текстовый, то сама собой решается проблема его кросс-платформенности, и точно так же легко решается проблема передачи XML-данных (как это, например, сделано в SOAP). Кроме того, можно без проблем изменять формат передачи или хранения данных, добавляя новые атрибуты и не сильно беспокоясь о совместимости с предыдущими версиями формата, поскольку приложения, использующие старую версию, смогут прочитать то, что им надо, не обращая внимания на новые теги или атрибуты. Многие приложения используют основанные на XML файловые форматы, многие протоколы передачи данных тоже основаны на XML, и списки тех и других продолжают расти.

Конечно, с другой стороны, XML не очень экономичен, потому что, как когда-то верно заметил один из посетителей форума "Компьютерных вестей", часто XML-документы состоят на 10% из данных и на 90% из тегов. Впрочем, это уже в значительной степени зависит от того, какие вы сами выберете теги. Можно написать ул. Мельникайте, 2, а можно . Хотя, если честно, мне кажется, что с нынешними винчестерами и толстыми каналами нет смысла особенно ужиматься.

Так что в умелых руках XML - вещь мощная и удобная, а из-за повсеместной распространённости этого формата от него и вовсе никуда не денешься. Поэтому давайте перейдём уже к написанию программного кода.

Для программирования мы будем использовать основной язык платформы.NET - C#. Для того, чтобы как можно больше читателей могли сами поупражняться с приведенным программным кодом, я буду использовать первую версию C# и.NET Framework"а.


Запись данных

Сначала поговорим о записи данных, поскольку, сами понимаете, чтобы что-то откуда-то считывать, нужно сначала что-то куда-то и записать. А коль скоро мы с вами занялись программированием, то создавать XML-данные "ручками" нам с вами не пристало. Поэтому давайте сначала займёмся записью данных в XML.

Для начала создайте новый проект в Visual Studio, #Develop"е или C# Builder"е, и в список импортируемых namespace"ов добавьте System.Xml.

За запись XML-данных в.NET Framework"е отвечает специальный класс XmlTextWriter, который позволяет записывать XML-данные в произвольный поток. То есть, мы, вообще говоря, можем записать их с его помощью и в файл, и в базу данных, и отправить кому-то через Интернет, однако сейчас мы будем писать всё именно в файл. Вы можете перенаправить вывод, изменив конструктор объекта (т.е. передав при инициализации не имя файла и его кодировку, а объект, являющийся потоком данных). Впрочем, я, кажется, уже стал забегать немного вперёд. Давайте сначала познакомимся с кодом, ответственным за запись данных в наш с вами XML-файл.

String FileName = "c:\\demo.xml"; XmlTextWriter xml = new XmlTextWriter(FileName, System.Text.Encoding.Unicode); xml.Formatting = Formatting.Indented; xml.WriteStartDocument(); xml.WriteStartElement("rootelement"); for (int i = 0; i < 10; i++) { xml.WriteStartElement("subelement"); xml.WriteAttributeString("attrib1", "value1"); xml.WriteAttributeString("attrib2", i.ToString()); for (int j = 0; j < 10; j++){ xml.WriteStartElement("subsubelement"); xml.WriteAttributeString("attr", j.ToString()); xml.WriteEndElement(); } xml.WriteEndElement(); } xml.WriteEndElement(); xml.WriteEndDocument(); xml.Close();

Первая строка, думаю, вполне ясна - это просто запись имени файла, в который мы будем сохранять данные. Дальше мы создаём объект типа XmlTextWriter (он называется, как видите, xml), и именно с ним мы будем производить все дальнейшие операции. Заметьте, что при конструировании объекта мы указываем и кодировку, в которой будет записываться XML: в нашем примере это Unicode. Следующая строчка, вообще говоря, не обязательна, однако она сделает наш XML-документ, что называется, human readable, то есть добавит нужные отступы и разобьёт его на строки. Без этого весь документ был бы записан одной строкой, что, хотя и экономит место, но делает его практически непригодным для ручного редактирования.

Начинается запись документа с вызова метода WriteStartDocument() нашего объекта xml. Следующая за ней строчка добавляет корневой элемент "rootelement" в наш XML-документ (напомню, для XML-документов корневой элемент должен присутствовать в единственном экземпляре). Далее мы в цикле добавляем ещё десять не несущих никакой смысловой нагрузки элементов в наш с вами XML-документ, для каждого из которых устанавливаем два атрибута и ещё по десять подэлементов. Обратите внимание, что мы можем добавлять к строке число без явной конвертации данных, а вот если число должно целиком образовывать строку, то его нужно преобразовывать явно методом ToString(). Также обратите внимание, что мы должны явно закрывать каждый из элементов нашего XML-документа, а также потом и весь документ целиком.

Теперь, когда наш XML-документ успешно записан, давайте посмотрим, каким образом можно считать из него данные.


Чтение данных

Добавьте на форму вашего приложения (если, конечно, оно у вас не консольное) компонент listBox для того, чтобы можно было следить за результатом чтения XML-файла. Ну а если ваша программа консольная , то вы с лёгкостью сможете перенаправить вывод на консоль.

Как обычно, сначала ознакомимся с кодом программы, а потом уже будем смотреть, что именно этот код делает.

XmlTextReader xml = new XmlTextReader(FileName); xml.WhitespaceHandling = WhitespaceHandling.None; int i = 0; while (xml.Read()){ if ((xml.NodeType == XmlNodeType.Element) & (xml.Name == "subelement")) { listBox1.Items.Add("subelement " + i + " found"); i++; listBox1.Items.Add(" " + xml.GetAttribute("attrib1")); listBox1.Items.Add(" " + xml.GetAttribute("attrib2")); while (xml.Read()&(xml.Name == "subsubelement")){ listBox1.Items.Add(" " + xml.GetAttribute("attr")); } } } xml.Close();

Для чтения, как вы могли заметить, мы используем уже другой класс, а именно - XmlTextReader. Он находится в том же пространстве имён, что и класс, который мы использовали для записи данных. В первой строчке мы создаём экземпляр XmlTextReader"а, имеющий имя xml (здесь мы предполагаем, что переменная FileName уже определена нами ранее). Чтобы пропускать пустые строки, ежели такие неким непостижимым образом возникнут в нашем только что созданном XML-файле, мы используем следующую строку в приведенном фрагменте кода. Переменная i используется для подсчёта количества найденных элементов "subelement" в XML-файле, из которого производится считывание данных.

Дальше идёт цикл непосредственного чтения данных из файла. Метод Read() считывает следующий элемент XML-документа, и после его считывания мы проверяем, что именно мы считали. Если это действительно элемент "subelement", то мы добавляем информацию о считанном элементе в listBox1, инкрементируем переменную, содержащую количество считанных элементов, а затем считываем атрибуты элемента. После чтения атрибутов мы организуем отдельный цикл для чтения подэлементов "subsubelement" (обратите внимание, что для этого нам не требуется отдельного XmlTextReader"а) и атрибутов этих подэлементов. Как и ранее, все считанные сведения мы заносим в listBox1, чтобы контролировать правильность чтения.

При чтении XML-файлов, точно так же, как и при их записи, при конструировании XmlTextReader"а можно указать в качестве параметра поток, из которого будет производиться чтение, и тогда читать можно будет не только из файлов, но также и из других источников, примеры которых я уже приводил выше. Следует отметить одну полезную особенность класса XmlTextReader: при чтении он не загружает в память весь читаемый XML-документ, поэтому с его помощью удобно проводить разбор больших XML-документов (например, XML баз данных).


За кадром

В общем-то, пример, который мы с вами только что разобрали, чересчур прост для реальных проектов. В наше время при чтении XML-документов, как правило, применяется их валидация с помощью DTD, XML Schema или Relax NG. Валидация - это проверка соответствия разметки XML-документа некоторому стандарту, описываемому во внешнем файле. Валидация нужна для того, чтобы проверка документа не была жёстко зашита в алгоритм программы, а могла изменяться произвольным образом при изменении в формате данных без обновления считывающего или записывающего данные программного кода. К сожалению, сейчас мы с вами уже разобрать валидацию не успеем, поскольку, как вы сами понимаете, объём газетной статьи имеет определённые ограничения.

Ещё один интересный и полезный практический момент, касающийся работы с XML-данными, - это XSL-преобразование данных. Это преобразование применяется к данным при их отображении на HTML-страницах и, фактически, просто является применением определённого шаблона web-страницы к XML-файлу с какими-либо данными. Поскольку львиная доля теперешнего использования XML-данных так или иначе приходится на World Wide Web, то и XSL-преобразования рассмотреть было бы очень и очень неплохо.

Так что, думаю, у этой статьи будет продолжение - но, конечно, только в том случае, если вы сами (то есть читатели "Компьютерных вестей") об этом попросите на форуме или в письме на мой электронный почтовый адрес. Пока же об использовании XML в.NET-приложениях, пожалуй, всё. Надеюсь, что эта информация будет полезной для вас.

Последнее обновление: 31.10.2015

Для работы с XML в C# можно использовать несколько подходов. В первых версиях фреймворка основной функционал работы с XML предоставляло пространство имен System.Xml . В нем определен ряд классов, которые позволяют манипулировать xml-документом:

    XmlNode : представляет узел xml. В качестве узла может использоваться весь документ, так и отдельный элемент

    XmlDocument : представляет весь xml-документ

    XmlElement : представляет отдельный элемент. Наследуется от класса XmlNode

    XmlAttribute : представляет атрибут элемента

    XmlText : представляет значение элемента в виде текста, то есть тот текст, который находится в элементе между его открывающим и закрывающим тегами

    XmlComment : представляет комментарий в xml

    XmlNodeList : используется для работы со списком узлов

Ключевым классом, который позволяет манипулировать содержимым xml, является XmlNode , поэтому рассмотрим некоторые его основные методы и свойства:

    Свойство Attributes возвращает объект XmlAttributeCollection , который представляет коллекцию атрибутов

    Свойство ChildNodes возвращает коллекцию дочерних узлов для данного узла

    Свойство HasChildNodes возвращает true , если текущий узел имеет дочерние узлы

    Свойство FirstChild возвращает первый дочерний узел

    Свойство LastChild возвращает последний дочерний узел

    Свойство InnerText возвращает текстовое значение узла

    Свойство InnerXml возвращает всю внутреннюю разметку xml узла

    Свойство Name возвращает название узла. Например, - значение свойства Name равно "user"

    Свойство ParentNode возвращает родительский узел у текущего узла

Применим эти классы и их функционал. И вначале для работы с xml создадим новый файл. Назовем его users.xml и определим в нем следующее содержание:

Microsoft 48 Google 42

Теперь пройдемся по этому документу и выведем его данные на консоль:

Using System.Xml; class Program { static void Main(string args) { XmlDocument xDoc = new XmlDocument(); xDoc.Load("users.xml"); // получим корневой элемент XmlElement xRoot = xDoc.DocumentElement; // обход всех узлов в корневом элементе foreach(XmlNode xnode in xRoot) { // получаем атрибут name if(xnode.Attributes.Count>0) { XmlNode attr = xnode.Attributes.GetNamedItem("name"); if (attr!=null) Console.WriteLine(attr.Value); } // обходим все дочерние узлы элемента user foreach(XmlNode childnode in xnode.ChildNodes) { // если узел - company if(childnode.Name=="company") { Console.WriteLine("Компания: {0}", childnode.InnerText); } // если узел age if (childnode.Name == "age") { Console.WriteLine("Возраст: {0}", childnode.InnerText); } } Console.WriteLine(); } Console.Read(); } }

В итоге я получу следующий вывод на консоли:

Чтобы начать работу с документом xml, нам надо создать объект XmlDocument и затем загрузить в него xml-файл: xDoc.Load("users.xml");

При разборе xml для начала мы получаем корневой элемент документа с помощью свойства xDoc.DocumentElement . Далее уже происходит собственно разбор узлов документа.

В цикле foreach(XmlNode xnode in xRoot) пробегаемся по всем дочерним узлам корневого элемента. Так как дочерние узлы представляют элементы , то мы можем получить их атрибуты: XmlNode attr = xnode.Attributes.GetNamedItem("name"); и вложенные элементы: foreach(XmlNode childnode in xnode.ChildNodes)

Чтобы определить, что за узел перед нами, мы можем сравнить его название: if(childnode.Name=="company")

Подобным образом мы можем создать объекты User по данным из xml:

List users = new List(); XmlDocument xDoc = new XmlDocument(); xDoc.Load("users.xml"); XmlElement xRoot = xDoc.DocumentElement; foreach(XmlElement xnode in xRoot) { User user = new User(); XmlNode attr = xnode.Attributes.GetNamedItem("name"); if (attr!=null) user.Name=attr.Value; foreach (XmlNode childnode in xnode.ChildNodes) { if (childnode.Name == "company") user.Company=childnode.InnerText; if (childnode.Name == "age") user.Age = Int32.Parse(childnode.InnerText); } users.Add(user); } foreach (User u in users) Console.WriteLine("{0} ({1}) - {2}", u.Name, u.Company, u.Age);