Пример программы 4.4


Атрибуты

В открывающем теге можно задавать дополнительные свойства элемента. Для этого используются атрибуты. Каждый атрибут задается парой "имя = "значение"". Например, если для элемента <Страна> надо указать столицу, то можно создать атрибут элемента с именем "столица". А для элемента <Школьник> задать атрибуты "возраст" и "класс". В приведенном ниже примере у элемента "Страна" со значением "Аргентина" атрибут "столица" имеет значение "Буэнос-Айрес".

Открывающий тег Значение элемента Закрывающий тег
Имя элемента Имя атрибута   Значение атрибута      
<Страна столица = "Буэнос-Айрес" > Аргентина </Страна>
             

Читать подобные документы не составляет труда, а поскольку они имеют четкую структуру, то и компьютер можно научить этому без особых проблем. Например, составить такой набор инструкций: "Начать просмотр документа; при нахождении символа " < " — читать имя элемента. При нахождении символа " > " — читать значение элемента..." и так далее.

Некоторые элементы могут иметь только атрибуты и не иметь значения и содержания. Тогда открывающий и закрывающий теги объединяются. Например, элемент <Страна>можно задать следующим образом:

<Страна название = "Аргентина" столица = "Буэнос-Айрес" />

Для описания элемента использовались два атрибута, но не значение элемента.

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

В ней используются три класса из пространства имен System.Xml:

  • XmlDocument. Объекты этого класса задают Xml-документ. При создании объекта содержимое документа может быть прочитано из файла, получено из других источников или создано в ходе работы программы.
  • XmlNodeList. Объекты этого класса могут содержать некоторый список элементов XML-документа, найденный, например, в результате поиска.
  • XmlNode. Объект этого класса задает один XML-элемент.

Для поиска нужных фрагментов XML-документа в программе используются так называемые выражения xPath. Они позволяют указать, какие именно элементы необходимо извлечь из XML-документа. Выражение xPath вида "/континент/страна" означает: "найти все элементы с именем "страна", вложенные в элемент с именем "континент"".

using System;

using System.Windows.Forms;

using System.Drawing;

// Пространство имен для работы с XML-данными

using System.Xml;

//Пространство имен для работы с выражениями xPath

using System.Xml.XPath;

class XmlRetriever: Form

{

ComboBox comboBox1;

Button button1;

ListBox listBox1;

RichTextBox richTextBox1;

XmlDocument xmlDoc;

 

// Метод-конструктор нашего класса

public XmlRetriever()

{

// Задаем заголовок и размеры окна

this.Text = "Работа с XML-документом";

this.Size = new Size(400, 400);

 

// Создаем объект XmlDocument, используя xml-файл

xmlDoc = new XmlDocument();

xmlDoc.Load("../../docs/Planets.xml");

 

// Создаем объект TextBox для вывода данных

richTextBox1 = new RichTextBox();

richTextBox1.Dock = DockStyle.Top;

richTextBox1.AcceptsTab = true;

richTextBox1.Height = 180;

richTextBox1.ReadOnly = true;

richTextBox1.BackColor = Color.Silver;

 

// Помещаем XML-данные в элемент TextBox

richTextBox1.Text = xmlDoc.OuterXml;

this.Controls.Add(richTextBox1);

 

// Создаем объект ComboBox

// В элементы списка этого объекта записываем

//различные выражения XPath,

//позволяющие искать нужные элементы XML-документа

comboBox1 = new ComboBox();

comboBox1.Location = new Point(0, 200);

comboBox1.Width = 300;

comboBox1.Items.Add("/Планета");

comboBox1.Items.Add("/Планета/Континент");

comboBox1.Items.Add("/Планета/Континент/Страна");

comboBox1.Items.Add(

"/Планета/Континент/Страна[@столица='Рио-де-Жанейро']");

comboBox1.SelectedIndex = 0;

this.Controls.Add(comboBox1);

 

// Создаем командную кнопку для поиска и отображения

// соответствующих элементов Xml-документа

button1 = new Button();

button1.Text = "Получить данные";

button1.Location = new Point(100, 230);

button1.Width = 120;

button1.Click += new EventHandler(Button1_Click);

this.Controls.Add(button1);

 

// Создаем элемент ListBox для отображения элементов

listBox1 = new ListBox();

listBox1.Dock = DockStyle.Bottom;

listBox1.Location = new Point(10, 10);

this.Controls.Add(listBox1);

}

 

static void Main()

{

// Создаем и запускаем новый экземпляр класса

Application.Run(new XmlRetriever());

}

 

// Обработчик события, срабатывающий при нажатии кнопки

void Button1_Click(object sender, EventArgs e)

{

XmlNodeList xmlNodes;

XmlNode xmlElement;

string elementValue;

 

// Используем охраняемый блок try-catch,

// что позволит в случае ошибок в выражениях XPath

// перехватывать обработку исключений, выдавать сообщение

// об ошибке и нормально продолжить работу приложения

try

{

// Выбираем из XML-документа элементы, которые соответствуют

// выражению XPath, заданному выбранным элементом ComboBox

xmlNodes = xmlDoc.SelectNodes(comboBox1.Text);

 

// Производим циклический перебор найденных элементов,

// добавляя каждый элемент в ListBox

listBox1.Items.Clear();

for (int i = 0; i < xmlNodes.Count; i++)

{

xmlElement = xmlNodes[i];

if (xmlElement.HasChildNodes)

{

elementValue = xmlElement.FirstChild.Value.Trim();

listBox1.Items.Add(elementValue);

}

}

}

catch (XPathException ex)

{

const string errorMessage =

"Ошибка в задании выражения XPath!" +

"\r\n" + "Соответствующие данные в документе не найдены!" +

"\r\n" + "Попробуйте задать другое выражение!";

MessageBox.Show(errorMessage +"\r\n" + ex.Message);

}

}

}