| Каталог | Индекс раздела |
© IBM deweloperWork
© А.С.Деревянко (перевод)
Этот учебник исследует проверку правильности XML-документов при помощи либо Описаний Типа Документов (Document Type Definition - DTD), либо схем XML. Он предназначен для разработчиков, которым нужно управлять типами и содержимым данных в их XML-документах, и предполагает, что вы знакомы с базовыми концепциями XML. (Вы можете получить базовое представление о самом XML в учебнике Введение в XML.) Он также предполагает базовое знакомство с пространствами имен XML. (Вы можете найти базовые сведения о пространствах имен в учебнике Понимание DOM.)
Этот учебник демонстрирует проверку правильности с использованием языка Java из командной строки, но принципы и концепции проверки правильности те же и для любой программной среды, так что опыт в технологии Java не является необходимым для достижения понимании. DTD и схема XML являются языково- и платформенно-независимыми.
При создании базы данных, использование модели данных в сочетании с ограничениями целостности дает гарантию, что структура и содержимое данных соответствуют требованиям. Но как вы проведете в жизнь этот вид контроля при использовании XML, когда ваши данные - это просто текст в файлах, которые можно редактировать вручную? К счастью, проверка правильности файлов и документов дает гарантию того, что данные соответствуют ограничениям. В этом учебнике вы изучите, что такое проверка правильности и как проверить документ по DTD или схеме XML документа.
DTD были исходно определены в XML 1.0 Recommendation и происходят из Standard Generalized Markup Language (SGML), предшественника HTML. Их синтаксис немного отличается от XML, что является одной из помех для их использования. Они также имеют ограничения в применении, что заставило разработчиков искать им альтернативу в схемах XML. Однако DTD все еще используются в значительном количестве сред, так что понимание их является важным.
Главной альтернативой DTD является рекомендация XML Schema, поддерживаемая консорциумом World Wide Web (W3C). (Во всем этом учебнике, "схема XML" является синонимом "схема XML W3C".) Схемы, которые также являются XML-документами, обеспечивают более знакомую и более мощную среду, в которой ограничения на данные могут существовать как XML-документ.
До конца учебника вы изучите, как создавать и DTD, и документ схемы XML. Вы также изучите концепции использования их для проверки правильности XML-документов.
Примеры этого учебника, если вы решите их выполнить, требуют, чтобы вы установили следующие инструменты и убедились, что они работают правильно. Выполнение примеров не является обязательным для понимания материала.
Если у вас инсталлирован другой набор инструментов, вы можете использовать его. Только проверьте в документации инструкции по настройке проверки правильности. Вы можете выгрузить реализации Xerces для C++ и Perl в проекте Apache на http://xml.apache.org.
Nicholas Chase, автор Studio B, участвовал в разработке Web-сайтов для таких компаний, как Lucent Technologies, Sun Microsystems, Oracle и Tampa Bay Buccaneers. Nick был преподавателем физики в высшей школе, менеджером низшего звена по использованию радиоактивных отходов, редактором онлайнового журнала научной фантастики, инженером по мультимедиа и инструктором по Oracle. В последнее время он - руководитель технического отдела фирмы Site Dynamics Interactive Communications в Clearwater, Florida, USA и автор четырех книг по Web-разработке, включая XML Primer Plus (Sams). Он любит слышать отзывы читателей, с ним можно связаться по адресу nicholas@nicholaschase.com.
XML-файлы разрабатываются так, чтобы они могли легко читаться и редактироваться людьми. Они также разрабатываются для легкого обмена данными между разными системами и разными приложениями.
К сожалению, оба эти преимущества могут работать против того, чтобы данные были в специфическом формате. Проверка правильности позволяет подтвердить, что XML-данные следуют заданной предопределенной структуре. Эта структура может быть обеспечена несколькими различными способами, включая DTD и схемы XML.
Документ, который был проверен таким способом по DTD или схеме, рассматривается, как правильный документ.
Поскольку слово правильный (valid) имеет другие значения в английском языке, оно иногда конфликтует со специфическим термином XML правильно форматированный (well formed).
Правильно форматированный документ соответствует правилам XML. Все элементы имеют начальные и конечные теги, все значения атрибутов заключены в кавычки, вложенность всех элементов корректна и т.д. Документ не может быть разобран, если он не является правильно форматированным.
Однако, только то, что документ может быть разобран, еще не означает, что он правильный в терминах XML. Чтобы считаться правильным, документ должен быть разобран проверяющим парсером со сравнением с предопределенной структурой.
Правильный документ всегда правильно форматирован, правильно форматированный документ может быть неправильным.
Когда XML изначально создавался, он был одним из приложений Стандартного Обобщенного Языка Разметки (Standard Generalized Markup Language - SGML). SGML дает возможность различным системам сообщаться друг с другом, позволяя авторам создавать DTD. Пока данные следуют DTD, каждая система может прочитать и интерпретировать их.
DTD определяют элементы, которые допустимы в документе, что они могут содержать и какие атрибуты они должны иметь.
Сравним этот простой документ с его DTD:
DTD
DTD использует синтаксис, отличный от XML, но оно описывает различные элементы и атрибуты и, как они могут применяться. Более подробная информация об использовании и создании DTD будет дана в этом учебнике позже, пока же отметим, что DTD связывается с XML-документами через оператор DTD выполняют свою задачу, но существуют и серьезные ограничения.
Во-первых, использование самого XML для описания структуры было бы значительно более удобным. Во-вторых, DTD имеют ограничения в том, что они могут определять. Не обеспечиваются типы данных и в некоторых случаях невозможны ограничения на порядок элементов. Это только некоторые из ограничений, с которыми сталкиваются разработчики при использовании DTD.
Схемы XML являются одной из альтернатив, которая была разработана, чтобы заполнить некоторые из этих пробелов. Рассмотрим тот же XML-документ, на этот раз с документом схемы.
XML-документ:
Схема XML:
Заметьте, что в этом случае синтаксис определения схемы отличается от синтаксиса DTD. Синтаксис определений схем предполагает, что их можно интерпретировать как XML-документы с определенной схемой, используя пространства имен XML вместо Полный пример XML-файла для проверки правильности в этом учебнике состоит из информации, которая является частью Проекта Памяти Тысячелетия, в котором собрана коллекция подаренных домашних видео и других записей личных историй для потомков.
Каждый экспонат содержит данные и информацию о них, такую, как имя дарителя, место и тема.
Документы, используемые для описания структуры файлов, являются простыми текстовыми файлами. Полезно, однако, понимать, как они используются приложением, которое выполняет конкретную проверку правильности. В этом учебники в примерах используется код Java, но вам необязательно действительно выполнять проверку правильности, чтобы понять конструкцию документов.
Прежде, чем XML-документы можно будет использовать, они должны быть разобраны, обычно с созданием либо документа DOM, либо потока SAX. В другом случае парсер рассматривает каждый символ документа и решает, является ли он элементом, атрибутом строкой данных и т.п.
Парсер может также проверять структуру документа по DTD или схеме, если он был сконфигурирован для этого. Это обычно делается в установках парсера или объекта, который создает парсер.
При проверке, если возникает проблема - такая, как неправильная вложенность элементов или ошибочные атрибуты, - вы должны обработать ее. Это делается посредством класса, который разрабатывается как обработчик ошибок.
Класс обработчика ошибок обычно расширяет вспомогательный класс Обработчик ошибок служит одной и только одной цели: иметь дело с нарушениями, которые возникают в ходе разбора документа.
Три типа ситуаций, которые могут возникать:
Каждая из этих ситуаций должна быть обработана соответствующим методом. В данном примере обработчик просто возвращает информацию о возникшей проблеме, а при появлении фатальной ошибке завершает работу.
Откомпилируйте этот класс, и он готов для того, чтобы к нему обращался парсер.
Как обсуждалось во введении этого учебника, нет необходимости кодировать и выполнять следующие примеры для понимания проверки правильности. Если же вы решите сделать это, использование код Java для разбора (и, разумеется, проверки правильности) документа включает в себя четыре шага. (В следующем подразделе обсуждается Проверка правильности в Xerces Java.):
Таковы базовые принципы: перед проверкой правильности документа создать проверяющий парсер, определить приемник ошибок проверки правильности и разобрать документ. (Если вы используете старую версию языка Java с парсером Xerces-Java, некоторые детали могут отличаться от описанных в подразделе Проверка правильности в Xerces Java.)
Использование Xerces для проверки правильности документа включает в себя те же базовые принципы, что и Проверка правильности в JAXP в предыдущем подразделе.
Приложение непосредственно создает экземпляр Вы можете задать местоположение документа схемы внутри XML (как в Документ экземпляра схемы XML), или можете задать его в самом приложении, используя свойство парсера, как было показано выше.
Далее назначается обработчик ошибок. Заметьте, что это тот же класс, который вы использовали для обработки ошибок в JAXP. Ошибки те же, так что у вас нет необходимости кодировать отдельный класс.
Наконец, разберите документ. Таким способом все документы проверяются по DTD или схеме.
Для проверки правильности документа вы должны иметь стандарт, по которому выполняется проверка. Раньше предполагалось, что задание требований к XML-документам происходит в DTD.
Когда идет речь о DTD, большинство людей лучше знакомо с внешним вариантом, в котором объявление DOCTYPE ссылается на файл, содержащий действующие определения.
Может быть использовано несколько способов для определения местонахождения DTD. Например, файл XHTML может определить DTD, которое определяет, следует ли он рекомендациям XHTML Strict, XHTML Transitional или XHTML Frameset, разработанным W3C. Чтобы определить XHTML Transitional, автор может задать:
Объявление Для прикладных DTD разработчики обычно используют идентификатор Части оператора соответствуют таковым для идентификатора Обычно, однако, объявление Внешний файл DTD просто содержит определение, начинающиеся с описанного в подразделе Элементы. Для внутреннего DTD эти определения являются частью самого XML-файла.
Внешнее DTD может определять содержимое многих разных документов, делая их в чем-то более легкими для управления. Однако иногда правильный документ нуждается в том, чтобы подтверждать сам себя. В этом случае вам нужно включать информацию DTD в сам документ.
Игнорируя на минутку реальное содержимое, обратите внимание на структуру внутреннего DTD. Объявление DOCTYPE продолжает содержать информацию, но вместо ссылки на локальный или удаленный файл, действующее DTD включается между скобками.
Независимо от того, имеем мы дело с внешними или внутренними DTD, элементы являются фундаментом XML-документов, так что они обычно определяются первыми.
Все определения элементов состоят из ключевого слова Элемент, который содержит текст, определяется с ключевым словом Элементы Элемент может также быть определен как Иногда автор хочет допустить возможность выбора для содержимого элемента. Например, структура данных содержит элемент с именем DTD, которое создавалось до сих пор, является весьма специфичным. Каждый элемент должен появляться один раз и точно в таком порядке. Единственным исключением из этого является Модификаторы предлагают большую гибкость в проекте. Они таковы:
Код, приведенный ниже, показывает DTD, модифицированный таким образом, что количество элементов Заметьте, что это ограничения на элемент. Элемент Порядок следования дочерних элементов может также быть определен по DTD. Парадоксально, но, хотя дочерние элементы должны всегда появляться в том порядке, в каком они появляются в DTD, DTD может быть написано так, чтобы дочерние элементы появлялись в любом порядке.
Коротко говоря, требуемый порядок не изменяется, но может выбираться. Например, это DTD задает, что элемент Если этот вариант может быть повторено, как в:
то В этом случае элементы могут появляться в любом порядке, поскольку DTD разрешает неограниченное число вариантов. Сначала может быть выбран Это серьезное ограничение DTD, и оно преодолено при помощи схем XML, которые обеспечивают гораздо большие возможности управления. Схемы также полезны при определении смешанного содержимого.
Одной из вариаций, которая не обсуждалась, являются элементы, которые имеют смешанное содержимое. Смешанное содержимое содержит и текст, и другие элементы. Хорошим примером является текст, содержащий разметку HTML. Рассмотрим следующий потенциальный Это то, что называют смешанным содержимым, потому что здесь есть и символьные данные, и элемент ( Заметьте, что хотя это и порождает некоторые проблемы, в DTD нет способа ограничить порядок. Это тоже проблема, решенная в схеме XML.
Хотя и возможно создать структуру XML, которая не содержит ничего, кроме элементов, более общей ситуацией является ситуация элементов с атрибутами. Атрибуты должны также быть определены, если они появляются в элементах правильного документа.
Вы можете определить атрибуты несколькими способами. Первый - просто определить их как символьные данные или В этом случае DTD назначает элементу memory атрибут Некоторые атрибуты перечисляемые, это значит, что значение должно выбираться из предопределенного списка. Например:
В этом случае документ должен выбрать значение из списка, если же значение не обеспечено, парсер использует значение по умолчанию Второй способ определения атрибутов включает в себя У вас может появиться необходимость связать данные при помощи использования идентификаторов, работа которых соответствует первичным и внешним ключам в реляционной базе данных. Например, может потребоваться, чтобы идентификатор Эта запись добавляет в файл два ограничения. Во-первых, значение каждого Каждый элемент может иметь максимум один атрибут Один из аспектов DTD, который часто игнорируется потому, что разработчики плохо его понимают, - сущности. Сущности появляются в двух разновидностях: параметрические сущности и общие сущности. Обе разновидности используются как макросы или переменные, обеспечивающие способ установить единственное значение, которое затем может быть использовано во многих местах.
Параметрическая сущность может быть использована только в пределах DTD. Она обычно применяется для создания определения, которое используется снова и снова, хотя может применяться для создания DTD с условиями. (Дополнительную информацию о DTD с условиями ищите в Ресурсы.)
Чтобы использовать параметрическую сущность, просто определите ее и ссылайтесь на нее. Например, вы можете определить содержимое элемента memory, а затем ссылаться на него в определении:
Параметрическая сущность содержит знак процента ( но она может использоваться только в самом документе:
Общие сущности могут также ссылаться на внешние документы, такие, как файл или URL, так что они могут применяться для заполнения информацией из других источников.
DTD:
Документ:
DTD чрезвычайно ограничены, если идет речь о реальных типах данных, которые могут в них включаться. Например, DTD не может ограничить данные только числовым типом или типом даты. Атрибуты могут быть ограничены уникальностью значений, как Ограничения могут также применяться к Порядку следования дочерних элементов. Кроме того, не более одного элемента может использовать определенное имя, так что вы не можете создать разные определения элемента, которые могут появляться в разных контекстах (таких, как потомки двух разных родителей).
Вы можете преодолеть эти трудности, используя схему XML.
В отличие от DTD, документы схемы XML строятся на самом XML. Проверка правильности при помощи схемы требует двух документов: документа схемы и документа экземпляра.
Документ схемы - это документ, содержащий структуру, а документ экземпляра содержит сами XML-данные. Приложение определяет схему для документа экземпляра одним из двух способов:
Сначала создайте само пространство имен, а затем используйте атрибут Документ схемы XML - это просто XML-документ с предопределенными элементами и атрибутами, описывающими структуру другого XML-документа.
Рассмотрим такой простой документ схемы:
Этот документ, являющийся схемой XML, эквивалентной DTD, построенному ранее в нашем учебнике, показывает некоторые структуры, используемые для определения содержимого XML-документов. Разработчик схемы начинает с определения элементов.
XML-документы строятся из элементов. Определение элемента в документе схемы XML состоит в придании ему имени и типа. Например:
Это простые элементы, которые содержат только текст. Элемент 42 простых типа определены как часть этой рекомендации, включая Вы также можете создавать новые типы.
Кроме встроенных простых типов, вы можете создавать новые простые типы. Спектр этих типов - от текста в определенном формате (такого, как телефонный номер или артикул товара) до числового ряда или перечисляемого списка.
Для проекта-примера нужно два новых простых типа. Первый - Этот тип, используемый для атрибута Вы можете использовать другой тип ограничения, создавая список перечислений, такой, как ограничивающий значения для типа носителя:
Вы можете использовать производные простые типы так же, как и встроенные типы.
Одно из ограничений для простого типа состоит в том, что такие элементы не могут содержать атрибутов. Чтобы добавить атрибуты в элемент, вы должны преобразовать его в Одним из способов сделать это является использование анонимных сложных типов. Он включает в себя добавление элемента В данном примере элемент Вы можете также создавать и именовать сложные типы.
Добавление в элемент потомков также требует использования сложных типов. Проще всего перечислить один или более дочерних элементов, используя элемент Этот пример показывает только один дочерний элемент, но вам все же нужен элемент В типе Тип Элемент sequence показывает все возможные дочерние элементы для данного элемента. В некоторых случаях, однако, вы хотите выбрать один элемент из списка альтернатив. Для этого вам нужен элемент Или элемент До сих пор все элементы и атрибуты, добавляемые в схему, должны были появляться ровно один раз. Очевидно, что это не всегда желательно. Используя Иногда вам не нужен верхний предел. Например, элемент Эта возможность становится очень полезной, когда мы имеем дело со смешанным содержимым в схеме.
Иногда элемент содержит смешанное содержимое, а не только элементы или только текст. Например, элемент Это содержимое не может быть описано как Этот метод создания смешанного содержимого является усовершенствованием по сравнению с DTD потому, что он позволяет лучше управлять количеством и порядком следования элементов. Конечно, в случае, если вы не хотите другого.
Иногда может ограничиваться содержимое элемента, но не порядок, в котором оно появляется. Это, в частности, так для смешанного содержимого в схемах. Чтобы создать элемент, который не ограничивает порядок его потомков, используйте элемент Заметьте, что Документы схемы также поддерживают полностью неограниченные элементы.
Полностью неограниченным элементом является такой, в котором разрешается какое угодно содержимое. Вы можете достичь этого через встроенный тип Комбинация всех этих приемов приводит к полному документу.
Документ схемы XML:
Документ экземпляра:
Этот учебник показал вам, как создавать и DTD, и документы схемы XML для проверки по ним ваших XML-документов. Обсуждалось также преимущество схем над DTD.
В этом учебнике также обсуждалась проверка правильности с точки зрения двух разных API Java (JAXP и Xerces). Однако XML является платформенно-независимым средством для представления информации; проверяющие парсеры доступны и в C++, и в Perl, и в других языках, и концепции их те же самые.
В Web есть много хорошей информации о проверке правильности XML-документов:
Пожалуйста, присылайте ваши отзывы об этом учебнике. Мы заинтересованы в том, чтобы услышать ваше мнение!
Кроме того, вы можете напрямую связаться с автором, Nicholas Chase, nicholas@nicholaschase.com
Что такое проверка правильности XML?
Инструменты
Об авторе
Раздел 2. Основы проверки правильности
Что такое проверка правильности?
Правильные и правильно форматированные
Определения Типа Документа (DTD)
<?xml version="1.0"?>
<!DOCTYPE memories SYSTEM "memory.dtd">
<memories>
<memory tapeid="23412">
<subdate>5/23/2001</subdate>
<donor>John Baker</donor>
<subject>Fishing off Pier 60</subject>
</memory>
<memory tapeid="23692">
<subdate>8/01/2001</subdate>
<donor>Elizabeth Davison</donor>
<subject>Beach volleyball</subject>
</memory>
</memories>
<!ELEMENT memories (memory*) >
<!ELEMENT memory (subdate, donor, subject) >
<!ATTLIST memory tapeid CDATA #REQUIRED >
<!ELEMENT subdate (#PCDATA) >
<!ELEMENT donor (#PCDATA) >
<!ELEMENT subject (#PCDATA) >
DOCTYPE.
Схемы XML
<?xml version="1.0"?>
<memories xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation=="'memory.xsd">
<memory tapeid="23412">
<subdate>5/23/2001</subdate>
<donor>John Baker</donor>
<subject>Fishing off Pier 60</subject>
</memory>
<memory tapeid="23692">
<subdate>8/01/2001</subdate>
<donor>Elizabeth Davison</donor>
<subject>Beach volleyball</subject>
</memory>
</memories>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="memories">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="memory" type="memoryType"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="memoryType">
<xsd:sequence>
<xsd:element name="subdate" type="xsd:date"/>
<xsd:element name="donor" type="xsd:string"/>
<xsd:element name="subject" type="xsd:string"/>
<xsd:attribute name="tapeid" type="idNumber" />
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
DOCTYPE.
Целевой документ
<?xml version="1.0"?>
<memories>
<memory tapeid="T1">
<media mediaid="T1" status="vhs" />
<subdate>2001-05-23</subdate>
<donor>John Baker</donor>
<subject>Fishing with the grandchildren on beautiful day.</subject>
<location><description>Pier 60</description></location>
</memory>
<memory tapeid="T2">
<media mediaid="T2" status="vhs"/>
<subdate>2001-05-18</subdate>
<donor>Elizabeth Davison</donor>
<subject>Beach volleyball</subject>
<location><place>Asbury Park, NJ</place></location>
</memory>
</memories>
Раздел 3. Проверка правильности документа
Как работает процесс проверки правильности
Создание обработчика ошибок
DefaultHandler, который реализует интерфейс ErrorHandler.
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.SAXParseException;
public class ErrorChecker extends DefaultHandler
{
public ErrorChecker() {
}
public void error (SAXParseException e) {
System.out.println("Parsing error: "+e.getMessage());
}
public void warning (SAXParseException e) {
System.out.println("Parsing problem: "+e.getMessage());
}
public void fatalError (SAXParseException e) {
System.out.println("Parsing error: "+e.getMessage());
System.out.println("Cannot continue.");
System.exit(1);
}
}
Проверка правильности в JAXP
DocumentBuilderFactory. Поскольку DocumentBuilder, который реально разбирает документ, является интерфейсом, экземпляр его не может быть создан непосредственно. Вместо этого создается DocumentBuilderFactory. Эта фабрика имеет определенные свойства, такие, как свойство isValidating(), которые определяют свойства любого созданного при его помощи парсера. Чтобы создать проверяющий парсер, примените setValidating(true) .
DocumentBuilder. Используйте DocumentBuilderFactory для создания объекта DocumentBuilder, который разбирает документ.
ErrorHandler. У парсера нет возможности проверять ваши проблемы, если он не знает, что с ними делать. Используйте метод setErrorHandler() класса DocumentBuilder, чтобы заставить парсер посылать ошибки новому объекту ErrorChecker, который был создан в подразделе Создание обработчика ошибок.
StructureTest, будет генерировать исключение. Если документ является правильно форматированным, но имеет ошибки проверки правильности, парсер посылает их в объект ErrorChecker, который рапортует о них.
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import org.w3c.dom.Document;
public class StructureTest {
public static void main (String args[]) {
File docFile = new File("memory.xml");
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(true);
DocumentBuilder db = dbf.newDocumentBuilder();
ErrorChecker errors = new ErrorChecker();
db.setErrorHandler(errors);
Document doc = db.parse(docFile);
} catch (Exception e) {
System.out.print("Parsing problem.");
}
}
}
Проверка правильности в Xerces Java
import org.apache.xerces.parsers.DOMParser;
import java.io.File;
import org.w3c.dom.Document;
public class SchemaTest {
public static void main (String args[]) {
File docFile = new File("memory.xml");
try {
DOMParser parser = new DOMParser();
parser.setFeature("http://xml.org/sax/features/validation", true);
parser.setProperty(
"http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation",
"memory.xsd");
ErrorChecker errors = new ErrorChecker();
parser.setErrorHandler(errors);
parser.parse("memory.xml");
} catch (Exception e) {
System.out.print("Problem parsing the file.");
}
}
}
DOMParser. Каждый парсер, созданный таким способом, имеет ряд свойств, одним из которых является возможность проверки правильности. Метод парсера setFeature() включает его.
ErrorChecker докладывает о любых ошибках.
Раздел 4. Определения Типа Документа (DTD)
Внешние DTD
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
DOCTYPE состоит из нескольких частей:
<!DOCTYPE: Показывает процессору, что это объявление DOCTYPE.
html: Показывает имя корневого элемента для документа. Если документ начинается с чего-то, отличного от <html> , он будет немедленно признан неправильным.
PUBLIC: DOCTYPE может определять распознаваемое публичное DTD, и хранить потенциальный путь к серверу для выборки его. Альтернатива, SYSTEM, показана ниже. Идентификатор SYSTEM показывает URI, по которому DTD может быть найдено.
"-//W3C//DTD HTML 4.01 Transitional//EN": Действующий публичный идентификатор для DTD Transitional XHTML.
SYSTEM, такой, как:
<!DOCTYPE memories SYSTEM "http://www.nicholaschase.com/memories.dtd">
PUBLIC, кроме объявления, показывающего местонахождение DTD.
DOCTYPE также задает идентификатор SYSTEM при использовании идентификатора PUBLIC на случай, если процессор не распознает последний:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
Структура внутреннего DTD
<?xml version="1.0"?>
<!DOCTYPE memories [
<!ELEMENT memories (memory+) >
<!ELEMENT memory (#PCDATA) >
>
<memories>
<memory>TBD</memory>
<memory>TBD</memory>
</memories>
Элементы
ELEMENT, имени элемента и содержимого, которое может в нем быть. Элемент может содержать текст, другие элементы или ничего вообще (в случае пустого элемента).
<!DOCTYPE memories [
<ELEMENT memories (memory) >
<ELEMENT memory (subdate, donor, subject, media) >
<ELEMENT subdate (#PCDATA) >
<ELEMENT donor (#PCDATA) >
<ELEMENT subject (#PCDATA) >
<ELEMENT media EMPTY >
]>
#PCDATA. Это сокращение для разбираемых символьных данных (parsed character data); оно относится к любому тексту внутри элемента и не может содержать разметку. Примерами являются элементы subdate, donor и subject.
memory и memories показывают синтаксис, используемый для задания элементов, которые содержат в себе только другие элементы.
EMPTY, как элемент media. Пустые элементы обычно несут всю информацию в атрибутах. Например:
<media type="vhs" />
Переменное содержимое элемента
location, который может содержать либо элемент place, либо элемент description. Это записывается следующим образом, с использованием символа вертикальной черты (|), разделяющего варианты:
<!ELEMENT location (place | description) >
<!ELEMENT place (#PCDATA) >
<!ELEMENT description (#PCDATA) >
Модификаторы (
*,+ и ?)location, где должен появляться либо place, либо description, но не оба вместе.
* : Элемент, определенный с модификатором *, может появляться 0 или более раз.
+ : Элемент, определенный с модификатором +, должен появляться 1 или более раз.
? : Элемент, определенный с модификатором ?, должен появляться 0 или 1 раз.
memory является неограниченным. Он также показывает, что требуется хотя бы один элемент subject, но допускается и более одного. Наконец, элемент donor не является обязательным, но если оно есть, оно может появляться только один раз. Немодифицированные элементы должны появляться один и только один раз.
<!DOCTYPE memories [
<!ELEMENT memories (memory)* >
<!ELEMENT memory (media,
subdate,
donor?,
subject+,
location) >
<!ELEMENT subdate (#PCDATA) >
<!ELEMENT donor (#PCDATA) >
<!ELEMENT subject (#PCDATA) >
<!ELEMENT location (place |
description) >
<!ELEMENT description (#PCDATA) >
<!ELEMENT place (#PCDATA) >
<!ELEMENT media EMPTY >
]>
donor может появляться только один раз в элементе memory, но может появляться в каждом экземпляре memory, если нужно.
Порядок следования дочерних элементов
location может иметь либо place, либо description:
<!ELEMENT location (place|description) >
<!ELEMENT location (place|description)* >
location может содержать place и description в любом порядке. То же самое может быть применено к элементу memory:
<!ELEMENT memory (media | subdate | donor?| subject+| location)* >
subdate, затем location, затем donor и т.д. Заметьте, однако, что если применен этот прием, то некоторые предыдущие ограничения становятся бесполезными. Поскольку варианты могут быть применены более одного раза, любой из заданных элементов может быть выбран любое число раз или вообще не выбран.
Смешанное содержимое в DTD
subject:
<subject>
A reading of Charles Dickens' <i>A Christmas Carol</i>.
Absolutely marvelous!
</subject>
<i></i>). Чтобы сделать его доступным для проверяющего парсера, должен быть определен элемент i, и элементу subject должно быть разрешено иметь любое число вариантов либо #PCDATA, либо i. Чтобы допустить общепринятую разметку, в DTD нужно иметь:
<!ELEMENT i (#PCDATA) >
<!ELEMENT b (#PCDATA) >
<!ELEMENT h1 (#PCDATA) >
<!ELEMENT br EMPTY >
<!ELEMENT p (#PCDATA) >
<!ELEMENT subject (#PCDATA|i|b|h1|br|p)* >
Определение атрибутов
CDATA:
<!ATTLIST memory tapeid CDATA #REQUIRED >
tapeid. Атрибут tapeid состоит из символьных данных и является обязательным. Элемент может также быть определен как #IMPLIED или #FIXED, в этом случае должно быть также задано значение по умолчанию.
<!ATTLIST media type (8mm | vhsc | vhs | audio) '8mm' #IMPLIED >
8mm. Это случай для любого документа, для которого существует DTD, даже, если парсер непроверяющий. В одном определении ATTLIST может быть определено много атрибутов:
<!ATTLIST media type (8mm | vhsc | vhs | audio) '8mm' #IMPLIED length CDATA >
ID и IDREF.
ID и IDREFmemory соответствовал идентификатору media, носителя, на котором эта запись размещена. Типы данных ID и IDREF позволяют вам обеспечить такую целостность данных:
<!ATTLIST media mediaid ID #REQUIRED >
<!ATTLIST memory tapeid IDREF #REQUIRED >
mediaid должно быть уникальным, значение каждого tapeid должно соответствовать существующему mediaid.
ID. Важно понимать, что все значения ID должны принадлежать к одному пулу (пространству значений). Если вы задаете более одного типа атрибутов ID, у вас нет способа заставить IDREF ссылаться на определенный атрибут ID.
Сущности
<!ENTITY % memorytype "media | subdate | donor?| subject+| location" >
<!ELEMENT memory (%memorytype;)* >
%), имя сущности и точку с запятой (;). Общая сущность также определяется в DTD:
<!ENTITY unknownLocation "<description>Unknown</description>" >
...
<memory tapeid="T1">
<media mediaid="T1" status="vhs" />
<subdate>2001-05-23</subdate>
<donor>John Baker</donor>
<subject>Fishing off Pier 60</subject>
<location>&unknownLocation;</location>
</memory>
...
Полное DTD и документ
<!ELEMENT memories (memory)* >
<!ELEMENT memory (media | subdate | donor?| subject+| location)* >
<!ATTLIST memory tapeid IDREF #REQUIRED >
<!ELEMENT subdate (#PCDATA) >
<!ELEMENT donor (#PCDATA) >
<!ELEMENT subject (#PCDATA) >
<!ELEMENT location (place|description) >
<!ELEMENT description (#PCDATA) >
<!ELEMENT place (#PCDATA) >
<!ELEMENT media EMPTY >
<!ATTLIST media mediaid ID #REQUIRED
status CDATA #IMPLIED>
<?xml version="1.0"?>
<!DOCTYPE memories SYSTEM "memory.dtd">
<memories>
<memory tapeid="T1">
<media mediaid="T1" status="vhs" />
<subdate>2001-05-23</subdate>
<donor>John Baker</donor>
<subject>Fishing off Pier 60</subject>
<location><description>Outside in the woods</description></location>
</memory>
<memory tapeid="T2">
<media mediaid="T2" status="vhs"/>
<subdate>2001-05-18</subdate>
<donor>Elizabeth Davison</donor>
<subject>Beach volleyball</subject>
<location><place>Clearwater beach</place></location>
</memory>
</memories>
Ограничения DTD
ID, но в DTD нет способа определить, какого типа данных они должны быть. (И, странно, ID не может быть числом, что противоречит общепринятой практике реляционных баз данных!)
Раздел 5. Схема XML
Документ экземпляра схемы XML
DOCTYPE для указания на внешнее DTD и используют атрибуты и пространства имен для указания на внешний документ схемы:
<?xml version="1.0"?>
<memories xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xsi:noNamespaceSchemaLocation='memory.xsd'>
<memory tapeid="idnum">
...
noNamespaceSchemaLocation для определения местоположения. Схемы могут также создаваться для определенного целевого пространства имен. В таком случае задавайте targetNamespace в самом документе схемы.
http://apache.org/xml/properties/schema/external-schemaLocation и http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation, чтобы определить местоположение документа схемы, как показано в Проверка правильности в Xerces Java.
Структура документа схемы
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="memories">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="memory" maxOccurs="unbounded" type="memoryType"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="memoryType">
<xsd:sequence>
<xsd:element name="media">
<xsd:complexType>
<xsd:attribute name="mediaid" type="xsd:string" />
<xsd:attribute name="status" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="subdate" type="xsd:string"/>
<xsd:element name="donor" type="xsd:string"/>
<xsd:element name="subject" type="xsd:string"/>
<xsd:element name="location" type="locationType" />
</xsd:sequence>
<xsd:attribute name="tapeid" type="xsd:string" />
<xsd:attribute name="status" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="locationType">
<xsd:choice>
<xsd:element name="description" type="xsd:string" />
<xsd:element name="place" type="xsd:string" />
</xsd:choice>
</xsd:complexType>
</xsd:schema>
Элементы и встроенные типы
<xsd:element name="subdate" type="xsd:date"/>
<xsd:element name="donor" type="xsd:string"/>
<xsd:element name="subject" type="xsd:string"/>
<xsd:element name="description" type="xsd:string" />
<xsd:element name="place" type="xsd:string" />
subdate, однако, должен быть ограничен датой в формате yyyy-mm-dd, как определено в рекомендации W3C XML Schema.
string, int, date, decimal, boolean, timeDuration и uriReference.
Простые типы: ограниченные значения
idNumber:
<xsd:simpleType name="idNumber">
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="1" />
<xsd:maxInclusive value="100000" />
</xsd:restriction>
</xsd:simpleType>
tapeid, просто ограничивает значение для целого числа между 1 и 100000.
Простые типы: перечисление
<xsd:simpleType name="mediaType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="8mm" />
<xsd:enumeration value="vhs" />
<xsd:enumeration value="vhsc" />
<xsd:enumeration value="digital" />
<xsd:enumeration value="audio" />
</xsd:restriction>
</xsd:simpleType>
Сложные типы: атрибуты
complexType.
complexType как потомка элемента element.
<xsd:element name="media">
<xsd:complexType>
<xsd:attribute name="mediaid" type="xsd:integer" />
<xsd:attribute name="status" type="mediaType" />
</xsd:complexType>
</xsd:element>
media имеет теперь два атрибута, включая атрибут перечисляемого типа mediaType.
Сложные типы: элементы
sequence:
<xsd:element name="memories">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="memory" type="memoryType"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
sequence.
memoryType комбинируются несколько приемов, увиденных вами недавно:
<xsd:complexType name="memoryType">
<xsd:sequence>
<xsd:element name="media">
<xsd:complexType>
<xsd:attribute name="mediaid" type="xsd:integer" />
<xsd:attribute name="status" type="mediaType" />
</xsd:complexType>
</xsd:element>
<xsd:element name="subdate" type="xsd:date"/>
<xsd:element name="donor" type="xsd:string"/>
<xsd:element name="subject" type="xsd:string"/>
<xsd:element name="location" type="locationType" />
</xsd:sequence>
<xsd:attribute name="tapeid" type="idNumber" />
<xsd:attribute name="status" type="xsd:string" />
</xsd:complexType>
memoryType также включает ссылку на locationType, что позволяет пользователю выбирать между потенциальными потомками элемента.
Выбор элементов
choice:
<xsd:complexType name="locationType">
<xsd:choice>
<xsd:element name="description" type="xsd:string" />
<xsd:element name="place" type="xsd:string" />
</xsd:choice>
</xsd:complexType>
description, или place - но не оба вместе - могут появляться в качестве потомков любого элемента locationType. Этот прием также может применяться для определения выбора атрибутов.
Необязательные и повторяющиеся элементы
minOccurs и maxOccurs, вы можете управлять тем, должен ли компонент появляться обязательно и может ли он повторяться. В данном примере схема требует, чтобы элемент subject присутствовал, и позволяет ему появляться до пяти раз в одном элементе:
...
<xsd:element name="subject" minOccurs="1" maxOccurs="5" type="xsd:string"/>
...
memory может быть определен как необязательный, но если он есть, он может появляться неограниченное число раз в элементе memories:
<xsd:element name="memories">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="memory"
minOccurs="0" maxOccurs="unbounded"
type="memoryType"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
Смешанное содержимое в схемах
subject может содержать разметку HTML:
<subject>
A reading of Charles Dickens' <i>A Christmas Carol</i>.
Absolutely <b>marvelous</b>!
</subject>
xsd:string, поскольку оно содержит элементы. Также и простое перечисление элементов i и b в последовательности не будет работать, поскольку они содержат текст. Вместо этого элемент subject должен быть определен как mixed:
<xsd:element name="subject">
<xsd:complexType mixed="true">
<xsd:sequence>
<xsd:element name="i" minOccurs="0" maxOccurs="unbounded"
type="xsd:string" />
<xsd:element name="b" minOccurs="0" maxOccurs="unbounded"
type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
Неограничиваемый порядок
all вместо sequence.
<xsd:element name="subject">
<xsd:complexType mixed="true">
<xsd:all>
<xsd:element name="i" minOccurs="0" maxOccurs="1" type="xsd:string" />
<xsd:element name="b" minOccurs="0" maxOccurs="1" type="xsd:string" />
</xsd:all>
</xsd:complexType>
</xsd:element>
maxOccurs установлен в 1, а не в unbounded. Это обязательно для применения элемента all. Атрибуты minOccurs и maxOccurs должны быть либо 0, либо 1. Комбинирование и вложение этих групп может создавать элементы, в которых ограничены типы элементов, но не их порядок или повторяемость.
Полностью неограниченные элементы
anyType. Например, вы можете определить элемент location содержащим любое содержимое, в любом порядке и с любой повторяемостью. Это включает в себя не только текст, но и элементы:
<xsd:element name="description" type="xsd:anyType" />
Полные документы схемы и экземпляра
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="memories">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="memory" minOccurs = "0" maxOccurs="unbounded"
type="memoryType"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="memoryType">
<xsd:sequence>
<xsd:element name="media">
<xsd:complexType>
<xsd:attribute name="mediaid" type="xsd:integer" />
<xsd:attribute name="status" type="mediaType" />
</xsd:complexType>
</xsd:element>
<xsd:element name="subdate" type="xsd:date"/>
<xsd:element name="donor" type="xsd:string"/>
<xsd:element name="subject">
<xsd:complexType mixed="true">
<xsd:all>
<xsd:element name="i" minOccurs="0" maxOccurs="1"
type="xsd:string" />
<xsd:element name="b" minOccurs="0" maxOccurs="1"
type="xsd:string" />
</xsd:all>
</xsd:complexType>
</xsd:element>
<xsd:element name="location" type="locationType" />
</xsd:sequence>
<xsd:attribute name="tapeid" type="idNumber" />
<xsd:attribute name="status" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="locationType">
<xsd:choice>
<xsd:element name="description" type="xsd:anyType" />
<xsd:element name="place" type="xsd:string" />
</xsd:choice>
</xsd:complexType>
<xsd:simpleType name="idNumber">
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="1" />
<xsd:maxInclusive value="100000" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="mediaType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="8mm" />
<xsd:enumeration value="vhs" />
<xsd:enumeration value="vhsc" />
<xsd:enumeration value="digital" />
<xsd:enumeration value="audio" />
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
<?xml version="1.0"?>
<memories xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xsi:noNamespaceSchemaLocation='memory.xsd'>
<memory tapeid="1">
<media mediaid="1" status="vhs" />
<subdate>2001-05-23</subdate>
<donor>John Baker</donor>
<subject>Fishing off Pier 60</subject>
<location>
<description>Outside in the woods</description>
</location>
</memory>
<memory tapeid="2">
<media mediaid="2" status="vhs"/>
<subdate>2001-05-18</subdate>
<donor>Elizabeth Davison</donor>
<subject>Beach volleyball</subject>
<location>
<place>Clearwater beach</place>
</location>
</memory>
</memories>
Раздел 6. Итоговая сводка проверки правильности
Резюме
Ресурсы
Обратная связь
| Каталог | Индекс раздела |