Пример программы 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);
}
}
}