Статьи

XML DTD против XML-схемы

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

XML позволяет системам UNIX, написанным на C, взаимодействовать с веб-службами, которые, например, работают на архитектуре Microsoft .NET и написаны на ASP.NET. Однако XML – это всего лишь метаязык, который понимают системы – и им обоим необходимо согласовать формат, в котором будут храниться данные XML. Как правило, один из партнеров в процессе предлагает услугу другому: один отвечает за формат данных.

Определение служит двум целям: во-первых, обеспечить, чтобы данные, прошедшие стадию синтаксического анализа, были, по крайней мере, в правильной структуре. Таким образом, это первый уровень, на котором ввод «мусора» может быть отклонен. Во-вторых, определение документирует протокол стандартным формальным способом, что облегчает разработчикам понимание того, что доступно.

DTD – Определение типа документа

Первым методом, использованным для предоставления этого определения, был DTD, или Определение типа документа. Это определяет элементы, которые могут быть включены в ваш документ, какие атрибуты имеют эти элементы, а также порядок и вложенность элементов.

DTD объявляется в объявлении DOCTYPE под объявлением XML, содержащимся в документе XML:

Встроенное определение:

<?xml version="1.0"?>  <!DOCTYPE documentelement [definition]> 

Внешнее определение:

 <?xml version="1.0"?>  <!DOCTYPE documentelement SYSTEM "documentelement.dtd"> 

Фактическое тело самого DTD содержит определения в терминах элементов и их атрибутов. Например, следующий короткий DTD определяет книжный магазин. В нем говорится, что у книжного магазина есть имя, и в нем есть книги по крайней мере по одной теме.

Каждая тема имеет название и 0 или более книг на складе. Каждая книга имеет название, автора и номер ISBN. Название темы и название книжного магазина определены как элементы одного типа: PCDATA: этого магазина PCDATA: только текстовые данные. Название и автор книги хранятся в виде CDATA -- текстовых данных, которые не будут анализироваться для дальнейших символов анализатором XML. Номер ISBN хранится как атрибут книги:

 <!DOCTYPE bookstore [  <!ELEMENT bookstore (topic+)>  <!ELEMENT topic (name,book*)>  <!ELEMENT name (#PCDATA)>  <!ELEMENT book (title,author)>  <!ELEMENT title (#CDATA)>  <!ELEMENT author (#CDATA)>  <!ELEMENT isbn (#PCDATA)>  <!ATTLIST book isbn CDATA "0">  ]> 

Примером встроенного определения книжного магазина может быть:

 <?xml version="1.0"?>  <!DOCTYPE bookstore [  <!ELEMENT bookstore (name,topic+)>  <!ELEMENT topic (name,book*)>  <!ELEMENT name (#PCDATA)>  <!ELEMENT book (title,author)>  <!ELEMENT title (#CDATA)>  <!ELEMENT author (#CDATA)>  <!ELEMENT isbn (#PCDATA)>  <!ATTLIST book isbn CDATA "0">  ]>  <bookstore>  <name>Mike's Store</name>  <topic>    <name>XML</name>    <book isbn="123-456-789">      <title>Mike's Guide To DTD's and XML Schemas<</title>      <author>Mike Jervis</author>    </book>  </topic>  </bookstore> 

Использование встроенного определения удобно, когда у вас есть только несколько документов, и они находятся в автономном режиме, так как определение всегда находится в файле. Однако, если, например, ваш DTD определяет протокол XML, используемый для связи между двумя отдельными системами, повторная передача DTD с каждым документом добавляет издержки к коммуникациям. Наличие внешнего DTD исключает необходимость повторной отправки каждый раз. Мы могли бы удалить DTD из документа и поместить его в файл DTD на веб-сервере, доступном для двух систем:

 <?xml version="1.0"?>  <!DOCTYPE bookstore SYSTEM "http://webserver/bookstore.dtd">  <bookstore>  <name>Mike's Store</name>  <topic>    <name>XML</name>    <book isbn="123-456-789">      <title>Mike's Guide To DTD's and XML Schemas<</title>      <author>Mike Jervis</author>    </book>  </topic>  </bookstore> 

Файл bookstore.dtd будет содержать полное определение в виде простого текстового файла:

   <!ELEMENT bookstore (name,topic+)>  <!ELEMENT topic (name,book*)>  <!ELEMENT name (#PCDATA)>  <!ELEMENT book (title,author)>  <!ELEMENT title (#CDATA)>  <!ELEMENT author (#CDATA)>  <!ELEMENT isbn (#PCDATA)>  <!ATTLIST book isbn CDATA "0"> 

Самый низкий уровень определения в DTD – это то, что является CDATA или PCDATA: символьные данные или проанализированные символьные данные. Мы можем только определить элемент как текст, и с этим ограничением невозможно, например, заставить элемент быть числовым. Атрибуты могут быть принудительно установлены в диапазоне определенных значений, но они не могут быть числовыми.

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

XML-схемы

XML-схемы предоставляют гораздо более мощные средства для определения структуры и ограничений вашего XML-документа. Схемы XML сами являются документами XML. Они ссылаются на пространство имен схемы XML (подробно здесь ) и даже имеют свои собственные DTD .

Что делают XML-схемы, так это предоставляют объектно-ориентированный подход к определению формата XML-документа. XML-схемы предоставляют набор основных типов. Эти типы гораздо шире, чем базовые PCDATA и CDATA DTD. Они включают в себя большинство основных типов программирования, таких как целые, байтовые, строковые и числа с плавающей запятой, но они также распространяются на типы данных Интернета, такие как коды страны и языка ISO (например, en-GB). Полный список можно найти здесь .

Затем автор XML-схемы использует эти основные типы вместе с различными операторами и модификаторами для создания собственных сложных типов. Эти сложные типы затем используются для определения элемента в документе XML.

В качестве простого примера давайте попробуем создать базовую XML-схему для определения книжного магазина, который мы использовали в качестве примера для DTD. Во-первых, мы должны объявить это как XSD-документ, и, поскольку мы хотим, чтобы это было очень удобно для пользователя, мы добавим к нему некоторую базовую документацию:

 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">  <xsd:annotation>  <xsd:documentation xlm:lang="en">    XML Schema for a Bookstore as an example.  </xsd:documentation>  </xsd:annotation> 

Теперь, в предыдущем примере, книжный магазин состоял из последовательности имени и хотя бы одной темы. Мы можем легко сделать это в XML-схеме:

 <xsd:element name="bookstore" type="bookstoreType"/>  <xsd:complexType name="bookstoreType">  <xsd:sequence>    <xsd:element name="name" type="xsd:string"/>    <xsd:element name="topic" type="topicType" minOccurs="1"/>  </xsd:sequence>  </xsd:complexType> 

В этом примере мы определили элемент bookstore , который будет соответствовать элементу XML в нашем документе. Мы определили его с типом bookstoreType , который не является стандартным типом, и поэтому мы даем определение этого типа далее.

Затем мы определяем complexType , который определяет bookstoreType как последовательность элементов имени и темы. Наш name" type « name" type – это xsd:string , тип, определенный пространством имен схемы XML, и поэтому мы полностью определили этот элемент.

Однако элемент topic имеет тип topicType , другой пользовательский тип, который мы должны определить. Мы также определили наш элемент темы с minOccurs="1", что означает, что должен быть хотя бы один элемент в любое время. Поскольку maxOccurs не определен, не существует верхнего предела для количества элементов, которые могут быть включены. Если бы мы не указали ни того, ни другого, по умолчанию был бы ровно один экземпляр, как это используется в элементе name . Далее мы определяем схему для topicType .

 <xsd:complexType name="topicType">  <xsd:element name="name" type="xsd:string"/>  <xsd:element name="book" type="bookType" minOccurs="0"/>  </xsd:complexType> 

Это все аналогично объявлению bookstoreType , но обратите внимание, что мы должны переопределить наш элемент name в рамках этого типа. Если бы мы использовали сложный тип для имени, такой как nameType , который определял только xsd:string – и определял его вне наших типов, мы могли бы повторно использовать его в обоих. Однако, чтобы проиллюстрировать это, я решил определить его в каждом разделе. XML становится интересным, когда мы даем определение нашему bookType :

 <xsd:complexType name="bookType">  <xsd:element name="title" type="xsd:string"/>  <xsd:element name="author" type="xsd:string"/>  <xsd:attribute name="isbn" type="isbnType"/>  </xsd:complexType>  <xsd:simpleType name="isbnType">  <xsd:restriction base="xsd:string">    <xsd:pattern value="[0-9]{3}[-][0-9]{3}[-][0-9]{3}"/>  </xsd:restriction>  </xsd:simpleType> 

Так что определение bookType не особо интересно. Но определение его атрибута ” isbn ” есть. XML-схема не только поддерживает использование таких типов, как xsd:nonNegativeNumber , но мы также можем создавать собственные простые типы из этих базовых типов, используя различные модификаторы. В isbnType выше примере для isbnType мы основываем его на строке и ограничиваем его для соответствия данному регулярному выражению. Исключая мое плохое регулярное выражение, это должно ограничить любой атрибут isbn, чтобы он соответствовал стандарту трех групп из трех цифр, разделенных чертой.

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

  • расширить ваши типы от других типов, которые вы создали,
  • требует уникальности в рамках, и
  • обеспечить поиск.

Это приятный объектно-ориентированный подход. Вы можете создать библиотеку complexTypes и simpleTypes для повторного использования во многих проектах и ​​даже найти другие определения общих типов (например, «адрес») из Интернета и использовать их для предоставления мощных определений ваших XML-документов. ,

DTD против XML-схемы

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

Итак, если XML-схемы предоставляют объектно-ориентированный подход к определению структуры XML-документа и если XML-схемы дают нам возможность определять многократно используемые типы, такие как номер ISBN, на основе широкого диапазона предопределенных типов, зачем нам использовать DTD? На самом деле есть несколько веских причин для использования DTD вместо схемы.

Во-первых, и, что немаловажно, XML-схема – это новая технология. Это означает, что, хотя некоторые парсеры XML поддерживают его полностью, многие до сих пор этого не делают. Если вы используете XML для связи с устаревшей системой, возможно, он не будет поддерживать XML-схему.

Многие системные интерфейсы уже определены как DTD. Это зрелые определения, богатые и сложные. Усилия по переписыванию определения могут не стоить.

DTD также установлен, и примеры общих объектов, определенных в DTD, имеются в Интернете – свободно доступны для повторного использования. Разработчик может использовать их для определения DTD быстрее, чем он сможет выполнить полную переработку основных элементов в виде новой схемы.

Наконец, вы также должны учитывать тот факт, что XML-схема является XML-документом. Он имеет пространство имен XML для ссылки и XML DTD для его определения. Это все накладные расходы. Когда синтаксический анализатор проверяет документ, ему, возможно, придется связать все это, взаимодействовать с DTD для схемы, загрузить пространство имен, проверить схему и т. Д., И все, прежде чем он сможет проанализировать фактический рассматриваемый документ XML. Если вы используете XML в качестве протокола между двумя системами, которые интенсивно работают и нуждаются в быстром ответе, то эти издержки могут серьезно снизить производительность.

С другой стороны, если ваша система доступна для сторонних разработчиков в качестве веб-службы, то подробное применение схемы XML может намного эффективнее защитить ваше приложение от вредоносных – или просто плохих – пакетов XML. Например, Muse.net – интересная технология. У них есть общедоступный SOAP API, определенный с помощью XML-схемы, который предоставляет их разработчикам больший контроль над тем, что они получают от сообщества пользователей.

С другой стороны, недавно я участвовал в разработке системы для обработки входящих транзакций с нескольких устройств. Для масштабирования системы выбранный сервис, обрабатывающий запросы, является сервером SOAP. Тем не менее, система полностью закрыта, и простого DTD на сервере достаточно, чтобы гарантировать, что пакеты, отправленные от клиентов, приходят в целости и сохранности, без дополнительных затрат на схему XML.