Книга: C# для профессионалов. Том II

Проверка

Проверка

Если нужно проверить документ XML, используйте класс XmlValidatingReader. Он обладает всей функциональностью класса XmlTextReader (оба реализуют XmlReader, но XmlValidatingReader добавляет свойство ValidationType, свойство Schemes и свойство SchemaType). Свойство ValidationType задается как тип проверки, которую желательно выполнить. Допустимые значения этого свойства следующие:

Значение свойства Описание
Auto Если в <!DOCTYPE...> объявлен DTD, он и будет загружаться и обрабатываться. Атрибуты по умолчанию и общие сущности, определенные в DTD, станут доступными. Если найден атрибут XSD schemalocation, то загружается и обрабатывается XSD, при этом все атрибуты по умолчанию, определенные в схеме, будут возвращены. Если найдено пространство имен с префиксом MSXML x-schema:, загрузится и обработается схема XDR, все атрибуты, определенные по умолчанию, возвратятся.
DTD Проверка согласно правилам DTD.
Schema Проверка согласно правилам XSD.
XDR Проверка согласно правилам XDR.
None Проверка не выполняется.

Если свойство задано, то должен быть назначен обработчик событий ValidationEventHandler. Событие инициируется, когда случается ошибка проверки. На ошибку можно отреагировать любым подходящим образом. Рассмотрим пример. Добавим пространство имен схемы XDR (XML Data Reduced — приведенные данные XML) к файлу books.xml и назовем этот файл booksVal.xml. Теперь он выглядит так:

<?xml version='1.0'?>
<!-- Этот файл представляет фрагмент базы данных учета запасов книжного склада -->
<bookstore xmlns="x-schema:books.xdr">
 <book genre="autobiography" publicationdate="1981" ISBN="1-861003-11-0">
  <title>The Autobiography of Benjamin Franklin</title>
  <author>
   <first-name>Benjamin</first-name>
   <last-name>Franklin</last-name>
  </author>
  <price>8.99</price>
 </book>
 <book genre="novel" publicationdate="1967" ISBN="0-201-63361-2">
  <title>The Confidence Man</title>
  <author>
   <first-name>Herman</first-name>
   <last-name>Melville</last-name>
  </author>
  <price>11.99</price>
 </book>
 <book genre="philosophy" publicationdate="1991" ISBN="1-861001-57-6">
  <title>The Gorgias</title>
  <author>
   <name>Plato</name>
  </author>
  <price>9.99</price>
 </book>
</bookstore>

Отметим, что элемент bookstore имеет теперь атрибут xmlns="x-schema:books.xdr". Это будет указывать на следующую схему XDR:

<?xml version="1.0"?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data" xmlns:dt="urn:schemas-microsoft-com:datatypes">
 <ElementType name="first-name" content="textOnly"/>
 <ElementType name="last-name" content="textOnly"/>
 <ElementType name="name" content="textOnly"/>
 <ElementType name="price" content="textOnly" dt:type="fixed.14.4"/>
 <ElementType name="author" content="eltOnly" order="one">
  <group order="seq">
   <element type="name"/>
  </group>
  <group order="seq">
   <element type="first-name"/>
   <element type="last-name"/>
  </group>
 </ElementType>
 <ElementType name="title" content="textOnlу" />
 <AttributeType name="genre" dt:type="string"/>
 <ElementType name="book" content="eltOnly">
  <attribute type="genre" required="yes"/>
  <element type="title"/>
  <element type="author"/>
  <element type="price"/>
 </ЕlementType>
 <ElementType name="bookstore" content="eltOnly">
  <element type="book"/>
 </ElementType>
</Schema>

Отметим, что имеются два атрибута в файле XML, которые не определены в схеме. Если посмотреть внимательно, то можно увидеть что в схеме нет атрибутов publication-date и ISBN из элемента book. Мы сделали это, чтобы показать, что проверка действительно выполняется. Можно использовать для подтверждения этого следующий код. Необходимо будет добавить в класс using System.Xml.Schema. Весь код доступен в XMLReaderSample5:

protected void button1_Click (object sender, System.EventArgs e) {
 //измените это в соответствии с используемой структурой путей доступа.
 string filename = "......booksVal.xml";
 XmlTextReader tr = new XmlTextReader(filename);
 XmlValidatingReader trv=new XmlValidatingReader(tr);
 // Задать тип проверки
 trv.ValidationType=ValidationType.xdr;
 // Добавить обработчик события проверки
 trv.ValidationEventHandler += new ValidationEventHandler(this.ValidationEvent);
 // Считываем узел за раз
 while(trv.Read()) {
  if (trv.NodeType == XmlNodeType.Text) listBox1.Items.Add(trv.Value);
 }
}
public void ValidationEvent(object sender, ValidationEventArgs args) {
 MessageBox.Show(args.Message);
}

Мы создаем XmlTextReader для передачи в XmlValidationReader. Когда XmlValidationReader trv создан, можно использовать его по большей части так же, как XmlTextReader в предыдущих примерах. Различия состоят в том что в данном случае определен атрибут ValidationType и добавлен ValidationEventHandler. Каждый раз при возникновении ошибки проверки инициируется ValidationEvent. Затем можно будет обработать ошибку проверки любым приемлемым способом. В данном примере выводится MessageBox с описанием ошибки. Вот как выглядит MessageBox, когда инициируется ValdationEvent.


В отличие от некоторых синтаксических анализаторов XmlValidationReader после возникновения ошибки продолжает считывание. Имеется возможность определить серьезность ошибки проверки. Если окажется, что это серьезная ошибка, то можно остановить чтение.

Свойство Schemas класса XmlValidationReader содержит коллекцию XmlSchemaCollection, которая находится в пространстве имен System.Xml.Schema. В этой коллекции находятся предварительно загруженные схемы XSD и XDR, что позволяет выполнить очень быструю проверку, (особенно, если нужно проверить несколько документов), так как схему не нужно каждый раз перезагружать. Для получения выигрыша в производительности и создается объект XmlSchemaCollection. Метод Add имеет четыре перегружаемые версии. Можно передать объект на основе XmlSchema, объект на основе XmlSchemaCollection, строку string с пространством имен вместе со строкой string с URL файла схемы и, наконец, строку string с пространством имен и объектом на основе XmlReader, который содержит схему.

Оглавление книги

Оглавление статьи/книги

Генерация: 0.531. Запросов К БД/Cache: 2 / 0
поделиться
Вверх Вниз