Работа с XML в .NET
Страница 4. Чтение документов с XmlValidatingReader


 

Чтение документов с XmlValidatingReader

    XmlValidatingReader обеспечивает проверку допустимости XML-документов на основе трех схем: XML Schema definition language (XSD), XML-Data Reduced (XDR) schema и DTD. XmlValidatingReader наследован от класса XmlReader и используется объекты класса XmlTextReader для получения XML-документа. Тип схемы устанавливается значением свойства ValidationType. Если же передать этому свойству значение ValidationType.None, то проверка производится не будет. По умолчанию значение свойства ValidationType равно ValidationType.Auto и тип схемы определяется автоматически.

  В нашем примере мы используем схему XSD. Для ее создания мы загрузили в Visual Studio .NET XML файл с заказами, выбрали в контекстном меню пункты Create Schema, отметили как обязательные атрибуты дату и адрес для заказа и цену и название для товара и убрали значение из атрибута для целевого пространства имен. В итоге получился следующий XSD-файл.

<?xml version="1.0" ?>
<xs:schema id="Заказы" xmlns:mstns="https://tempuri.org/заказы.xsd"
xmlns="https://tempuri.org/заказы.xsd" xmlns:xs="https://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
attributeFormDefault="qualified" elementFormDefault="qualified">
  <xs:element name="Заказы" msdata:IsDataSet="true" msdata:Locale="ru-RU" msdata:EnforceConstraints="False">
    <xs:complexType>
        <xs:choice maxOccurs="unbounded">
          <xs:element name="Заказ">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="Товар" minOccurs="0" maxOccurs="unbounded">
                  <xs:complexType>
                    <xs:attribute name="Название" form="unqualified" type="xs:string" use="required" />
                    <xs:attribute name="Цена" form="unqualified" type="xs:string" use="required" />
                  </xs:complexType>
                </xs:element>
              </xs:sequence>
              <xs:attribute name="Адрес" form="unqualified" type="xs:string" use="required" />
              <xs:attribute name="Дата" form="unqualified" type="xs:string" use="required" />
            </xs:complexType>
          </xs:element>
        </xs:choice>
     </xs:complexType>
  </xs:element>
</xs:schema>

    Рассмотрим функцию, выполняющую проверку допустимости XML-документа с заказами на основе XSD-схемы.

OpenFileDialog dlg = new OpenFileDialog();
dlg.Filter = "Файлы XML (*.xml)|*.xml";

if (dlg.ShowDialog() != DialogResult.OK)
    return;

string file = dlg.FileName;

// получаем имя файла со схемой
dlg.Filter = "Файлы XSD (*.xsd)|*.xsd";

if (dlg.ShowDialog() != DialogResult.OK)
    return;

string schema = dlg.FileName;
XmlValidatingReader readerVal = null;
orders.Clear();

try
{
    XmlTextReader reader = new XmlTextReader(file);
    reader.WhitespaceHandling = WhitespaceHandling.None; // пропускаем пустые узлы
    readerVal = new XmlValidatingReader(reader);
    readerVal.Schemas.Add("", schema);
    readerVal.ValidationType = ValidationType.Schema;
    readerVal.ValidationEventHandler += new ValidationEventHandler(ValidationEventHandle);

    while (readerVal.Read())
        if (readerVal.NodeType == XmlNodeType.Element)
            if (readerVal.Name == "Заказ")
            {
                 Order order = new Order(readerVal.GetAttribute("Адрес"), DateTime.Parse(readerVal.GetAttribute("Дата")));
                 // получаем товары в заказе
                 while (readerVal.Read() && readerVal.Name == "Товар")
                      order.AddGood(readerVal.GetAttribute("Название"), float.Parse(readerVal.GetAttribute("Цена")));
                 orders.Add(order);
            }

     ShowOrders();
}
catch (XmlException ex)
{
    MessageBox.Show(ex.Message);
}
catch (Exception ex)
{
    MessageBox.Show("Ошибка: " + ex.Message);
}
finally
{
    if (readerVal != null)
        readerVal.Close();
}

    Вначале создаем объект XmlTextReader и передаем ему имя файла, указанное пользователем. Затем создаем XmlValidatingReader, который и будет отвечать за проверку допустимости документа. Затем добавляем XSD-схему из файла, указанного пользователем. Первым параметром в функции Add идет пространство имен (у нас передана пустая строка). Если же в вашем случае задано пространство имен, то его нужно определять из XSD-файла, получив значение атрибута targetNamespace у тега schema. Затем мы указываем тип схемы и определяем обработчик ValidationEventHandle события, который будет вызываться в случае возникновения ошибок или предупреждений. Тип события (ошибка или предупреждение) можно определить с помощью значения ValidationEventArgs.Severity, передаваемого обработчику. Также с помощью атрибутов можно получить дополнительную информацию об ошибке (ValidationEventArgs.Exception) и текстовое описание ошибки (alidationEventArgs.Message). Если мы не определим обработчик, то в случае определения недопустимости XML-документа будет возникать исключение XmlException, а предупреждения будут игнорироваться. На рисунке приведен диалог с сообщением об ошибке.

  

    Как и в случае в XmlTextReader мы в цикле вызываем метод Read для перебора всех узлов документа. Сам процес разбора документа так же ни чем не будет отличать от работы с XmlTextReader.

 
« Предыдущая статья   Следующая статья »