Перейти к содержимому

Создание валидных XML-документов

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

    Основной критерий для валидного документа

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

    Корректно сформированный XML-Документ также может быть валидным. Валидным (valid) называется корректно сформированный (well-formed) документ, отвечающий двум дополнительным требованиям:

    • пролог документа должен содержать специальное объявление типа документа, которое содержит определение типа документа (DTD), задающее структуру документа;
    • остальной документ должен отвечать структуре, заданной в DTD.

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

    Требования корректности формирования и валидности

    Требования корректности формирования представляют собой набор правил, определенных в спецификации XML в дополнение к основным синтаксическим требованиям. Поскольку XML-документ должен быть корректно сформированным, любое отклонение от требований корректности формирования считается фатальной ошибкой (fatal error). Если XML-процессор сталкивается с фатальной ошибкой, он останавливает нормальную обработку документа и не пытаться ее во зобновить.

    Требования валидности представляют собой дополнительный набор правил в спецификации XML, которым вы должны следовать, чтобы создать валидный документ. Поскольку валидность является не обязательной для XML-документа, отклонение от требований валидноcти считается лишь ошибкой (error), но не фатальным сбоем. Если XML- процессор встречает ошибку, он может просто выдать сообщение о ней и продолжить обработку. Требования валидности состоят из специальных правил по созданию соответствующего объявления типа с его DTD, а также созданию документа, отвечающего описанию внутри вашего DTD. 

    Преимущества использования валидных ХМ L- документов

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

    Однако, если вы хотите быть уверенным, что ваш документ отвечает определенной структуре или набору стандартов, включение DTD, которое описывает эту структуру, дает возможность XML-процессору (например, Microsoft Internet Explorer 5) проверить, соответствует ли документ структуре. Другими словами, DTD обеспечивает стандартный шаблон для процессора, чтобы при проверке валидности он мог следовать требуемой структуре и гарантировать, что ваш документ соответствует установленным стандартам. Если какая-либо часть документа не отвечает DTD-cne-цификации, процессор может отобразить сообщение об ошибке, чтобы вы могли отредактировать документ и исправить несоответствия.

    Использование валидных документов особенно полезно для проверки однородности среди группы схожих документов. Фактически, стандарт XML определяет DTD как «грамматику для определенного класса документов».

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

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

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

    Совет. Если вы открываете XML-документ (самостоятельный или с присоединенной таблицей стилей) непосредственно в Internet Explorer 5, процессор Internet Explorer 5 проверяет весь документ (в том числе объявление типа документа, если оно присутствует) на корректность формы составления, и выводит сообщение о фатальной ошибке при любом обнаруженном несоответствии. Однако процессор Internet Explorer 5 не проверяет документ на валидность.

    Чтобы проверить документ на валидность, вы можете использовать сценарий проверки на валидность, приведенный в главе 9 в разделе «Проверка валидности XML-документа». Прочтите приведенные в этом разделе указания уже сейчас, чтобы проверять на валидность ваши XML-документы.

    Добавление DTD

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

    Объявление типа документа определяет структуру документа. Если вы открываете документ, не содержащий объявления типа, в Internet Explorer 5, процессор Internet Explorer 5 всего лишь осуществляет проверку документа на корректность формы составления. Если же вы открываете документ, содержащий объявление типа документа, процессор Internet Explorer 5 будет проверять документ на валидность вместе с проверкой на корректность формы составления, так что ваш документ должен отвечать всем имеющимся декларациям в объявлении типа документа. Так, вы не сможете включить в документ какие-либо элементы или атрибуты, если вы не объявили их в объявлении типа документа. Каждый элемент и атрибут, который вы включаете, должен соответствовать спецификации (например, допустимости применения данного содержимого элемента или типа атрибута), выраженной в соответствующем объявлении.

    Примечание. Процессор Internet Explorer 5 проверяет документ на валидность только в том случае, если вы открываете документ через HTML Web-страницу (с использованием техники, с которой вы познакомитесь в главах 8 и 9). Если вы открываете XML-документ непосредственно в Internet Explorer 5, процессор будет проверять документ (включая любое объявление типа документа, которое он содержит) на корректность формы составления, но не будет проверять документ на валидность, даже если он содержит объявление типа документа.

    Форма записи DTD

    Объявление типа документа имеет следующую обобщенную форму записи:

    <!DOCTYPE Имя DTD>

    Здесь Имя указывает на имя элемента Документ. Имя действительного элемента Документ должно в точности соответствовать имени, записанному в объявлении. (Правила, в соответствии с которыми следует выбирать имена элементов, приведены в разделе «Анатомия элемента» в главе 3.) Например, если вы объявляете тип документа для документа, рассмотренного в предыдущем разделе, вам следует использовать имя INVENTORY:

    <!DOCTYPE INVENTORY DTD>

    (Это еще не законченное объявление типа документа. DTD следует заменить реальным содержимым.)

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

    Примечание. Подобно всем ключевым словам XML, DOCTYPE должно быть набрано прописными буквами.

    Создание DTD

    DTD состоит из символа левой квадратной скобки ([), после которой следует ряд объявлений разметки, заканчивающихся правой квадратной скобкой (]). Объявления разметки описывают логическую структуру документа, т.е. задают элементы документа, атрибуты и другие компоненты. На следующем рисунке приведен законченный валидный XML-доку-мент, содержащий DTD с единственным объявлением разметки, которое определяет один тип элемента в документе, SIMPLE.

    DTD в этом примере документа указывает, что документ может содержать только элементы типа SIMPLE (это единственный заданный тип элемента), и что элемент SIMPLE может иметь любое допустимое для данного типа содержимое (ключевое слово ANY).

    DTD может содержать следующие типы объявлений разметки.

    • Объявления типов элементов. Они определяют типы элементов, которые может содержать документ, а также содержимое и порядок следования элементов. Об объявлениях типов элементов пойдет речь в следующем разделе.
    • Объявления списков атрибутов. Каждое объявление списков атрибутов задает имена атрибутов, которые могут быть использованы с определенным типом элемента, а также типы данных и устанавливаемые по умолчанию значения этих атрибутов. Об этих объявъявлениях будет рассказано далее в этой главе.
    • Объявления примитивов. Вы можете использовать примитивы для  хранения часто используемых фрагментов текста или для встраивания не относящихся к XML данных в ваш документ. Об объявлениях примитивов будет рассказано в главе 6.
    • Объявления нотаций. Нотация описывает формат данных или идентифицирует программу, используемую для обработки определенного формата. Об объявлениях нотаций пойдет речь в главе 6.
    • Инструкции по обработке. Эта тема затрагивалась в разделе «Использование инструкций по обработке» в главе 4.
    • Комментарии. О них говорилось в разделе «Добавление комментариев» в главе 4.
    • Ссылки на параметрические примитивы. Любой из приведенных выше компонентов может содержаться внутри параметрического примитива и добавляться путем ссылки на параметрический примитив. Смысл этого оператора станет вам понятен, когда вы познакомитесь с материалом из главы 6. Данный пункт приведен здесь для полноты картины.

    Примечание. Типы DTD, обсуждаемые в этом разделе (и используемые в примерах в последующих разделах), относятся к внутреннему подмножеству DTD, поскольку полностью включаются в объявление типа данного документа. В конце этой главы вы узнаете, как использовать DTD, размещенные в отдельном файле, и относящиеся к внешнему подмножеству DTD.

    Объявление типов элементов

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

    Форма записи объявления типа элемента

    Объявление типа элемента имеет следующую обобщенную форму: 

    <!ELEMENT Имя опись_содержимого>

    Здесь Имя есть имя объявляемого типа элемента. (Свод правил по правильному заданию имен элементов приведен в разделе «Анатомия элемента» в главе 3.)  Опись одержимого — это описание содержимого, которое определяет, что может содержать элемент. В следующем разделе приведены различные типы описаний содержимого, которые вы можете использовать.

    Ниже приведено объявление типа элемента с именем TITLE, для содержимого которого могут использоваться только символьные данные (дочерние элементы не допускаются):

    <!ELEMENT TITLE (#PCDATA)>

    А вот объявление для типа элемента с именем GENERAL, содержимое которого может быть любым:

    <!ELEMENT GENERAL ANY>

    В качестве последнего примера рассмотрим законченный XML-документ с двумя типами элементов. Объявление типа элемента COLLECTION указывает, что он может содержать один или несколько элементов CD, a объявление типа элемента CD указывает, что он может содержать только символьные данные. Заметим, что документ соответствует этим объявлениям, и, следовательно, является валидным:

    <?xml version=»1.0″?> <!DOCTYPE COLLECTION

    [

    <!ELEMENT COLLECTION (CD)+>

    <!ELEMENTCD(#PCDATA)>

    <!— Вы также можете включать комментарии в DTD. —>

    >

    <COLLECTION>

    <CD>Mozart Violin Concertos 1,2, and 3</CD>

    <CD>Telemann Trumpet Concertos</CD>

    <CD>Handel Concetti Grossi Op. 3</CD> 

    </COLLECTION>

    Примечание. Вы можете объявить определенный тип элемента в данном документе только один раз.

    Описание содержимого элемента

    Вы можете описать содержимое элемента — т.е. заполнить часть описъ_содер-жимого в объявлении типа элемента — четырьмя различными способами.

    • Пустое содержимое (EMPTY). Ключевое слово EMPTY указывает, что элемент должен быть пустым, т.е. не может иметь содержимого. Например:

    <!ELEMENT IMAGE EMPTY>

    Ниже приведены валидные элементы IMAGE, которые вы можете поместить в документ:

    <IMAGEX/IMAGE> <IMAGE/>

    • Любое содержимое (ANY). Ключевое слово ANY указывает, что элемент может иметь любое допустимое для этого типа содержимое. Элемент этого типа может содержать или не содержать дочерние элементы в любом порядке и с любым количеством вхождений, иметь или не иметь чередующиеся символьные данные. Это наиболее неопределенный тип описания содержимого, он дает возможность создавать типы элементов без ограничений на их содержимое. Вот пример соответствующего объявления:

    <!ELEMENTMISCANY>

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

    Задание содержимого элемента

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

    Рассмотрим следующий пример XML-документа, описывающий одну книгу:

    <?xmlversion=»1.0″?> 

    <!DOCTYPE BOOK

    [

    <!ELEMENT BOOK (TITLE, AUTHOR)> 

    <!ELEMENT TITLE (#PCDATA}> 

    <!ELEMENT AUTHOR (#PCDATA)>

    >

    <BOOK>

    <TITLE>The Scarlet Letter</TITLE>

    <AUTHOR>NathanielHawthorne</AUTHOR> 

    </BOOK>

    В этом документе тип элемента BOOK объявлен как имеющий содержимое элемента. (TITLE, AUTHOR), следующие за именем элемента в объявлении, составляют модель содержимого. Модель содержимого указывает на разрешенные типы дочерних элементов и их порядок. В этом примере модель содержимого указывает на то, что элемент BOOK должен иметь ровно один дочерний элемент TITLE, за которым следует ровно один дочерний элемент AUTHOR. При обработке документа процессор игнорирует три пустых строки, используемые для разделения дочерних элементов внутри элемента BOOK. Модель содержимого может иметь одну из следующих основных форм.

    • Последовательная. Последовательная форма модели содержимого указывает, что элемент должен иметь заданную последовательность дочерних элементов. Вы отделяете имена типов дочерних элементов запятыми. Например, следующее DTD указывает, что элемент MOUNTAIN должен иметь один дочерний элемент NAME, после которого идет один дочерний элемент HEIGHT, за которым следует один дочерний элемент STATE:

    <!DOCTYPE MOUNTAIN

    [

    <!ELEMENT MOUNTAIN (NAME, HEIGHT, STATE)>

    <!ELEMENT NAME (#PCDATA)>

    <!ELEMENT HEIGHT (#PCDATA)> 

    <!ELEMENT STATE (#PCDATA)>

    ]

    >

    Следовательно, следующий элемент Документ будет валидным:

    <MOUNTAIN>

    <NAME>Wheeler</NAME>

    <HEIGHT>13161</HEIGHT>

    <STATE>New Mexico</STATE> 

    </MOUNTAIN>

    Следующий элемент Документ, однако, не будет валидным, поскольку порядок дочерних элементов не соответствует объявленному:

    <MOUNTAIN> <!— Неправильный элемент! —>

    <STATE>New Mexico</STATE>

    <NAME>Wheeler</NAME>

    <HEIGHT>1316K/HEIGHT> 

    </MOUNTAIN>

    Пропуск дочернего элемента или использование одного и того же типа дочернего элемента более одного раза также недопустимо. Как вы видите, это достаточно строгий вид объявления.

    • Выборочная. Выборочная форма модели содержимого указывает, что элемент может иметь любой из серии допустимых дочерних элементов, разделяемых символом |. Например, следующее DTD указывает, что элемент FILM может состоять из одного дочернего элемента STAR, или одного дочернего элемента NARRATOR, или одного дочернего элемента INSTRUCTOR:

    <!DOCTYPEFILM 

    [

    <!ELEMENT FILM (STAR | NARRATOR | INSTRUCTOR)>

    <!ELEMENT STAR (#PCDATA)> 

    <!ELEMENT NARRATOR (#PCDATA)> 

    <!ELEMENT INSTRUCTOR (#PCDATA)>

    >

    Следовательно, следующий элемент Документ будет валидным:

    <FILM>

    <STAR>Robert Redford</STAR> 

    </FILM>

    как и элемент:

    <FILM>

    <NARRATOR>Sir Gregory Parsloe</NARRATOR> 

    </FILM>

    а также элемент:

    <FILM>

    <INSTRUCTOR>GalahadThreepwood</INSTRUCTOR> 

    </FILM>

    Следующий элемент Документ не будет валидным, поскольку вы можете включить только один из дочерних элементов:

    <FILM> <!— Неправильный элемент! —>

    <NARRATOR>Sir Gregory Parsloe</NARRATOR> 

    <INSTRUCTOR>GalahadThreepwood</INSTRUCTOR>

    </FILM>

    Вы можете изменить любую из этих форм модели содержимого, используя знак вопроса (?), знак плюс (+) и звездочку (*), значения которых описаны в следующей таблице:

    СимволЗначение
    ?Ни одного или один из предшествующих элементов
    +Один или несколько из предшествующих элементов
    *Ни одного или несколько из предшествующих элементов

    Например, следующее объявление означает, что вы можете включить один или более дочерних элементов NAME, и что дочерний элемент HEIGHT является не обязательным:

    <!ELEMENT MOUNTAIN (NAME+, HEIGHT?, STATE)> 

    Таким образом, следующий элемент будет правильным:

    <MOUNTAIN>

    <NAME>Pueblo Peak</NAME>

    <NAME>Taos Mountain</NAME>

    <STATE>New Mexico</STATE> 

    </MOUNTAIN>

    Другой пример: следующее объявление означает, что вы можете включить несколько или ни одного дочернего элемента STAR, либо один дочерний элемент NARRATOR, либо один дочерний элемент INSTRUCTOR:

    <!ELEMENT FILM (STAR* | NARRATOR | INSTRUCTOR)>

    Соответственно, каждый из следующих трех элементов будет корректным:

    <FILM>

    <STAR>Tom Hanks</STAR>

    <STAR>Meg Ryan</STAR> 

    </FILM> 

    <FILM>

    <NARRATOR>Sir Gregory Parsloe</Narrator> 

    </FILM> 

    <FILM/>

    Вы также можете воспользоваться символами ?, + или * для модификации всей модели содержимого, помещая символы непосредственно после закрывающих скобок. Например, следующее объявление дает вам возможность включить один или несколько дочерних элементов любого из этих трех типов в любом порядке:

    <!ELEMENT FILM (STAR | NARRATOR | INSTRUCTOR)+> 

    Такое объявление делает корректными следующие элементы: 

    <FILM>

    <NARRATOR>BertramWooster</NARRATOR>

    <STAR>Sean Connery</STAR>

    <NARRATOR>Plug Basham</Narrator> 

    </FILM> 

    <FILM>

    <STAR>Sean Connery</STAR>

    <STAR>Meg Ryan</STAR> 

    </FILM> 

    <FILM>

    <INSTRUCTOR>StinkerPike</INSTRUCTOR> 

    </FILM>

    Наконец, вы можете формировать более сложные модели содержимого путем вложения выборочной модели содержимого внутрь последовательной модели, либо последовательной модели в выборочную модель. Например, следующее DTD задает, что каждый элемент FILM должен иметь ()дин дочерний элемент TITLE; за ним должен следовать один дочерний элемент CLASS; после него должен идти один дочерний элемент STAR, N Л RRATOR или INSTRUCTOR:

    <!DOCTYPE FILM

    [

    <!ELEMENT FILM (TITLE, CLASS, (STAR | NARRATOR | INSTRUCTOR) )>

    <!ELEMENT TITLE (#PCDATA)>

    <!ELEMENT CLASS (#PCDATA)>

    <!ELEMENT STAR (#PCDATA)>

    <!ELEMENT NARRATOR (#PCDATA)>

    <!ELEMENT INSTRUCTOR (#PCDATA)>

    >

    В соответствии с этим DTD, следующий элемент Документ будет корректным:

    <FILM>

    <TITLE>The Net<AITLE>

    <CLASS>fictionaK/CLASS>

    <STAR>Sandra Bullok</STAR> 

    </FILM>

    так же, как такой:

    <FILM>

    <TITLE>How to Use XML<AITLE>

    <CLASS>instructionaK/CLASS>

    <INSTRUCTOR>PennyDonaldson</INSTRUCTOR> 

    </FILM>

    Задание смешанного содержимого

    Если элемент имеет смешанное содержимое, он может включать символьные данные. Если же вы зададите в объявлении один или несколько типов дочерних элементов, он может содержать любые из этих дочерних элементов в любом порядке и с любым количеством вхождений (нуль и более). Другими словами, при смешанном содержимом вы можете задавать типы дочерних элементов, но не можете задавать порядок или количество вхождений дочерних элементов, а также задавать обязательность включения для определенных типов дочерних элементов.

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

    • Только символьные данные. Чтобы объявить тип элемента, который может содержать только символьные данные, используйте модель содержимого (#PCDATA). Так, следующее объявление указывает, что для элемента SUBTITLE допускаются только символьные данные:

    <!ELEMENT SUBTITLE (#PCDATA)>

    Следующие два элемента в соответствии с данной декларацией являются корректными:

    <SUBTITLE>A New Approach</SUBTITLE> 

    <SUBTITLE></SUBTITLE>

    Заметим, что элемент, который в соответствии с объявлением должен содержать символьные данные, может и не иметь никаких символов, т.е. быть пустым.

    Примечание. Ключевое слово PCDATA относится к синтаксически анализируемым (разбираемым) символьным данным. Из главы 3 вам известно, что XML-процессор синтаксически разбирает символьные данные внутри элемента, т.е. сканирует элемент в поиске XML-разметки. В связи с этим вы не можете использовать правую угловую скобку (<) или знак амперсанда (&) или символы ]]> как часть символьных данных, поскольку синтаксический анализатор будет интерпретировать каждый из этих символов или группы символов как разметку. Однако вы можете использовать любые символы с помощью ссылки на символ или на предопределенный примитив (см. главу 6) или с помощью раздела CDATA (см. главу 4).

    • Символьные данные с необязательными дочерними элементами. Чтобы объявить тип элемента, который может содержать символьные данные плюс ни одного или несколько дочерних элементов, перечислите каждый тип дочернего элемента после ключевого слова PCDATA в модели содержимого, разделяя их символами | и помещая звездочку (*) в конце всей модели содержимого. Каждое имя элемента может появляться в модели содержимого только один раз. Например, следующее объявление указывает, что элемент TITLE может содержать символьные данные плюс ни одного или несколько дочерних элементов SUBTITLE:

    <!ELEMENT TITLE (SPCDATA | SUBTITLE)*>

    В соответствии с этим объявлением следующие элементы TITLE являются допустимыми:

    <TITLE>

    Moby-Dick

    <SUBTITLE>Or, the Whale</SUBTITLE> 

    </TITLE>

    <SUBTITLE>Or, the Whale</SUBTITLE> 

    Moby-Dick 

    </TITLE> 

    <TITLE>

    Moby-Dick 

    </TITLE> 

    <TITLE>

    <SUBTITLE>Or, theWhale</SUBTITLE>

    <SUBTITLE>Another Subtitle</SUBTITLE> 

    </TITLE> 

    <ТITLE>

    </TITLE>

    Объявление атрибутов

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

    • определяет имена атрибутов, ассоциированных с элементом. В валидном документе вы можете включить в начальный тег элемента только те атрибуты, которые определены для элемента;
    • устанавливает тип данных каждого атрибута;
    • задает востребованность для каждого атрибута. Если атрибут не востребован, в объявлении списка атрибутов указывается, что должен делать процессор, если атрибут опущен. (В объявлении должно, например, содержаться значение атрибута по умолчанию, которое будет использовать процессор.)

    Форма записи объявления списка атрибутов

    Объявление списка атрибутов имеет следующую общую форму: 

    <!ATTLIST Имя ОпрАтр>

    Здесь Имя представляет собой имя элемента, ассоциированного с атрибутом или атрибутами. OnpAmp — это одно или несколько определений атрибутов, каждое из которых определяет один атрибут.

    Определение атрибута имеет следующую форму записи:

    Имя ОпрАгр ОбъявУмолч

    Здесь Имя представляет собой имя атрибута. (Правила выбора имен атрибутов приведены в разделе «Правила создания атрибутов в главе 3.)

    OnpAmp представляет собой тип атрибута, т.е. виды значений, которые могут быть присвоены атрибуту. (О типах атрибутов пойдет речь в следующем разделе.) ОбъявУмолч — это объявление по умолчанию, которое указывает на востребованность атрибута и содержит другую информацию. (Об этом будет рассказано далее в этой главе.)

    Допустим, вы объявили тип элемента с именем FILM следующим образом: 

    <!ELEMENT FILM (TITLE, (STAR | NARRATOR | INSTRUCTOR) )>

    Вот пример объявления списка атрибутов, которое описывает два атрибута — Class и Year — для элемента FILM:

    <!ATTUST FILM Class CDATA «fictional» Year CDATA #REQUIRED> 

    На следующем рисунке представлены составные части этого объявления.

    Вы можете присвоить атрибуту Class любую строку в кавычках (ключевое слово CDATA); если вы опускаете атрибут для определенного элемента, ему будет автоматически присвоено значение по умолчанию «fictional». Вы можете присвоить атрибуту Year любую строку в кавычках; этот атрибут, однако, должен быть обязательно присвоен для каждого элемента FILM (ключевое слово #REQUIRED), поэтому он не имеет значения по умолчанию.

    Следующий полный XML-документ включает это объявление списка атрибутов, а также элемент FILM:,

    <?xmlversion=»1.0″?> 

    <!DOCTYPE FILM

    [

    <!ELEMENT FILM (TITLE, (STAR | NARRATOR | INSTRUCTOR) )>

    <!ATTUSTFILM Class CDATA «fictional» Year CDATA #REQUIRED> 

    <!ELEMENT TITLE (#PCDATA)> 

    <!ELEMENT STAR (#PCDATA)> 

    <!ELEMENT NARRATOR (#PCDATA)> 

    <ELEMENT INSTRUCTOR (#PCDATA)>

    >

    <FILM Year=»1948″>

    <TITLE>The Morning Аfter</TITLE>

    <STAR>Morgan Attenbury</STAR> 

    </FILM>

    Для элемента FILM атрибуту Year присвоено значение «1948». Атрибут Class опущен; однако, поскольку этот атрибут имеет значение по умолчанию («fictional»), оно присваивается атрибуту, как если бы вы записали его в качестве значения атрибута.

    Примечание. Если вы использовали для данного типа элемента более одного объявления списка атрибутов, содержания двух объявлений объединяются. Если атрибут с заданным именем объявлен для одного и того же элемента несколько раз, первое объявление используется, а последующие — игнорируются. (Множественные объявления списков атрибутов могут иметь место, если документ имеет как внутренние, так и внешние DTD, о чем пойдет речь далее в этой главе.)

    Тип атрибута

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

    Вы можете задавать тип атрибута тремя различными способами.

    • Строковый тип. Строковый тип атрибута может быть назначен любой строке в кавычках (литералу), которая отвечает общим правилам, описанным в разделе «Правила для корректного задания значений отрибутов» в главе 3. Вы должны объявить строковый тип атрибута с использованием ключевого слова CDATA, как это сделано для определения атрибута Class в следующем примере:

    <!ATTUST FILM Class CDATA «fictional»>

    • Маркерный тип. Значения, которые вы можете присваивать атрибуту маркерного типа, имеют ряд ограничений (см. следующий раздел).
    • Нумерованный тип. Для нумерованного типа атрибута вы можете присваивать одно значение или список определенных значений. Об этом типе вы узнаете в разделе «Задание нумерованных типов» далее в этой главе.

    Задание маркерного типа

    Как и любое значение атрибута, значение, которое вы присваиваете маркерному типу атрибута, должно представлять собой строку в кавычках, отвечающую общим правилам, описанным в разделе «Правила для корректного задания значений атрибутов» в главе 3.

    Кроме того, значение должно отвечать определенному ограничению, которое вы задаете в описании атрибута с помощью соответствующего ключевого слова. Например, в приведенном ниже XML-документе для атрибута StockCode определен маркерный тип с использованием ключевого слова ID. (ID — это только одно из ключевых слов, которые вы можете использовать для объявления маркерного типа.) Это ключевое слово означает, что для каждого элемента атрибуту должно быть присвоено уникальное значение. (Например, присвоение товарного кода «S021» двум элементам ITEM не допускается.)

    <?xml version=»1.0″?> <!DOCTYPE INVENTORY

    [

    <!ELEMENT INVENTORY (ITEM*)>

    <!ELEMENT ITEM (#PCDATA)>

    <!ATTLIST ITEM StockCode ID #REQUIRED>

    >

    <INVENTORY>

    <!— Каждый элемент ITEM должен иметь свое значение кода StockCode —> 

    <ITEM StockCode=»S021″>Peach Tea Pot</ITEM> 

    <ITEM StockCode=»S034″>Electric Cofee Grinder</ITEM> 

    <ITEM StockCode=»S086″>Candy Thermometer</ITEM>

    </INVENTORY>

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

    • ID. Для каждого элемента атрибут должен иметь уникальное значение. Значение должно начинаться с буквы или символа подчеркивания (_), за которыми могут идти или не идти другие буквы, цифры, символы точки (.), тире (-) или символы подчеркивания. Данный тип элемента может иметь только один атрибут типа ID, а в объявлении значения атрибута по умолчанию должно фигурировать #REQUIRED или #IMPLIED (см. в разделе «Объявление значения по умолчанию» далее в этой главе). Пример этого типа атрибута содержится в приведенном выше документе INVENTORY.
    • IDREF. Значение атрибута должно совпадать со значением атрибута элемента типа ID внутри документа. Другими словами, этот тип атрибута является ссылкой на уникальный идентификатор другого атрибута. Например, вы можете добавить атрибут IDREF с именем GoesWith к элементу ITEM:

    <!ELEMENT ITEM (#PCDATA)> 

    <!ATTLIST ITEM

    StockCode ID «REQUIRED GoesWith IDREF #IMPLIED>

    Далее вы можете использовать этот атрибут для ссылки на другой элемент ITEM:

    <IТЕМ StockCode=»S034″>Electric Cofee Grinder</ITEM> 

    <ITEM StockCode=»S047″ GoesWith=»S034″

    Cofee Grinder Brush

    </ITEM>

    • IDREFS. Этот тип атрибута похож на тип IDREF, но при этом значение может включать ссылки на несколько идентификаторов — разделенных пробелами — внутри строки в кавычках. Например, если вы назначите атрибуту GoesWith тип IDREFS таким образом:

    <!ATTUST ITEM StockCode ID «REQUIRED GoesWith IDREFS #IMPLJED>

    то можете использовать его на ссылки на несколько других элементов:

    <ITEM StockCode=»S034″>Electric Cofee Grinder</ITEM> 

    <ITEM StockCode=»S039″>

    1 pound Breakfast Blend Cofee Beans

    </IТЕМ> 

    <ITEM StockCode=»S047″ GoesWith=»S034 S039″>

    Cofee Grinder Brush 

    </ITEM>

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

    Например, в DTD вы объявляете элемент с именем IMAGE, представляющий графическое изображение, и атрибут типа ENTITY с именем Source, указывающий на источник графических данных:

    <!ELEMENT IMAGE EMPTY>

    <ATTLJST IMAGE Source ENTITY #REQUIRED>

    Если вы объявили не анализируемый примитив с именем Logo (используя технику, с которой вы познакомитесь в главе 6), который содержит графические данные для изображения, вы можете присвоить этот примитив атрибуту Source элемента IMAGE в документе следующим образом:

    <IMAGESource=»Logo»/>

    • ENTITIES. Этот тип атрибута похож на тип ENTITY, за исключением того, что значение может содержать имена нескольких не анализируемых примитивов — разделенных пробелами — внутри строки в кавычках. Например, если вы назначили атрибуту Source тип ENTITIES следующим образом:

    <!ELEMENT IMAGE EMPTY>

    <!ATTUST IMAGE Source ENTITIES #REQUIRED>

    то сможете использовать его для ссылки на несколько не анализируемых примитивов (допустим, примитивов, содержащих графические данные в альтернативных форматах), например, так:

    <IMAGE Source-‘LogoGif LogoBmp» />

    (Здесь подразумевается, что LogoGif и LogoBmp — имена не анализируемых примитивов, которые были объявлены в DTD с помощью приемов, с которыми вы познакомитесь в главе 6.)

    • NMTOKEN. Это значение есть элементарное имя (name token), представляющее собой имя, состоящее из одной или более букв, цифр, точек (.), тирг ( ) или символов подчеркивания (_). Элементарное имя может также содержать двоеточие (:), но не на первом месте. Например, если вы назначите атрибуту ISBN тип NMTOKEN следующим образом:

    <!ELEMENT BOOK (#PCDATA)> 

    <!ATTUSTBOOK ISBN NMTOKEN #REQUIRED>

    то можете присвоить ему значение, начинающееся с цифры (цифры в качестве первых символов допустимы только для маркерных типов NMTOKEN и NMTOKENS):

    <ВООК ISBN=»9-99999-999-9″>The Portrait of a Lady</BOOK>

    • NMTOKENS. Этот тип атрибута похож на тип NMTOKEN, но значение может содержать несколько элементарных имен — разделенных пробелами — внутри строки в кавычках. Например, если вы назначите атрибуту Codes тип NMTOKENS следующим образом:

    <!ELEMENT SHIRT (#PCDATA)>

    <!ATTUST SHIRT Codes NMTOKENS #REQUIRED>

    вы можете присвоить ему несколько значений в виде элементарных имен:

    <SHIRTCodes=»38 21 97′>long sleeve Henley</SHIRT>

    Задание нумерованных типов

    Как любое значение атрибута, значение, которое вы присваиваете нумерованному типу, должно представлять собой строку в кавычках, отвечающую правилам, описанным в разделе «Правила для корректного задания значений атрибутов» в главе 3. Помимо этого, значение должно совпадать с одним из имен, приведенных в списке типов атрибутов. Эти имена могут иметь одну из следующих двух форм записи.

    • Открывающая скобка, вслед за которой идет список элементарных имен, разделенных символами, после чего следует закрывающая скобка. Напомним, что элементарное имя — это имя, состоящее из одной или нескольких букв, цифр, точек (.), тире (—) или символов подчеркивания (_), а также может включать одно двоеточие (:), но не на первом месте. Например, если вы хотите ограничить значения атрибута Class словами «fictional», «instructional» или «documentary», то можете определить это атрибут как нумерованный тип следующим образом:

    <!ATTLIST FILM

    Class (fictional | instructional | documentary) 

    «fictional»

    Вот законченный XML-документ, демонстрирующий использование атрибута Class:

    <?xml version=»1.0″?> 

    <!DOCTYPEFILM

    [

    <!ELEMENT FILM (TITLE, (STAR | NARRATOR | INSTRUCTOR) )>

    <!ATTLIS TFILM

    Class (fictional | instructional | documentary) «fictional»> 

    <!ELEMENT TITLE (#PCDATA) 

    <!ELEMENTSTAR(#PCDATA) 

    <!ELEMENT NARRATOR(#PCDATA) 

    <!ELEMENT INSTRUCTOR (#PCDATA)

    >

    <FILM Class=»instructional»>

    <TITLE>The Use and Care of ХМL</TITLE>

    <NARRATOR>Michael Young</NARRATOR> 

    </FILM>

    Если вы опустили атрибут Class, ему будет по умолчанию присвоено значение «fictional». Присвоение атрибуту Class значения, отличного от «fictional», «instructional» или «documentary», приведет к ошибке.

    • Ключевое слово NOTATION, за которым идет пробел, затем открывающая скобка, затем список имен нотаций, разделяемых символами, после чего следует закрывающая скобка. Каждое из этих имен должно точно соответствовать имени нотации, объявленному в DTD. Нотация описывает формат данных или идентифицирует программу, применяемую для обработки определенного формата (подробнее о нотациях будет рассказано в главе 6).

    Например, в вашем DTD объявлены нотации HTML, SGML и RTF. Тогда вы можете ограничить значения атрибута Format одним из этих имен нотаций с помощью следующего объявления:

    <!ELEMENT EXAMPLE_DOCUMENT (#PCDATA)> 

    <!ATTLJST EXAMPLE DOCUMENT

    Format NOTATION (HTML | SGML | RTF) #REQUIRED>

    В дальнейшем вы можете использовать элемент Format для указания формата определенного элемента EXAMPLE_DOCUMENT, как в следующем примере:

    <EXAMPLE DOCUMENT Format=»HTML»> 

    <![CDATA[ 

    <HTML> 

    <HEAD>

    <TITLE>Mike’s Home Рage</TITLE> 

    </HEAD> 

    <BODY>

    <P>Welcome!</P> 

    </BODY> 

    </HTML>

    ]]> 

    </EXAMPLE_DOCUMENT>

    Присвоение атрибуту Format значения, отличного от «HTML», «SGML» или «RTF», приведет к ошибке. (Обратите внимание на использование здесь раздела СВАТА — при этом вы можете свободно использовать символ левой угловой скобки (<) внутри символьных данных элемента.)

    Объявление значения по умолчанию

    Объявление значения по умолчанию — это третий и последний обязательный компонент в определении атрибута. Оно задает, является ли атрибут обязательным, и если нет, указывает, что должен предпринимать процессор в случае, когда атрибут опущен (см. рисунок ниже). Так, объявление должно обеспечить значение атрибута по умолчанию, которое будет использовать процессор в том случае, если атрибут отсутствует.

    Объявление значения по умолчанию может иметь следующие четыре формы:

    •  #REQUIRED. При этой форме вы должны задать значение атрибута для каждого элемента ассоциированного типа. Например, следующее объявление указывает, что вы должны присвоить значение атрибуту (Паяя внутри начального тега каждого элемента FILM в документе:

    <!ATTLJST FILM Class CDATA #REQUIRED>

    •  #IMPLIED. Эта форма указывает, что вы можете либо включить, либо опустить атрибут для элемента ассоциированного типа, а также, что если вы опускаете атрибут, то никакое значение по умолчанию процессору не передается. (Эта форма «подразумевает», а не «устанавливает» значение, позволяя приложению использовать свое собственное значение по умолчанию — т.е. имя.) Например, следующее объявление указывает, что присвоение значения атрибуту Class внутри элемента FILM является не обязательным, и что в документе не представлено значение Class по умолчанию:

    <!ATTUSTFILM Class CDATA #IMPLIED>

    • AttValue, где AttValue — значение атрибута по умолчанию. При такой форме вы можете либо включить, либо опустить атрибут для элемента ассоциированного типа. Если вы опускаете атрибут, процессор использует значение по умолчанию, как если бы вы включили атрибут и задали это значение.

    Задаваемое значение по умолчанию, конечно, должно соответствовать заданному типу атрибута. Например, следующее объявление присваивает значение по умолчанию «fictional» атрибуту Class:

    <!ATTLIST FILM Class CDATA «fictional»> 

    Согласно этому объявлению следующие два элемента эквивалентны:

    <FILM>The Graduate</FILM>

    <FILM Class=»fictional»>The Graduate</FILM>

    •  #FIXED AttValue, где AttValue — значение атрибута по умолчанию. При такой форме вы можете либо включать, либо опускать атрибут для элемента ассоциированного типа. Если вы опускаете атрибут, процессор будет использовать значение, заданное по умолчанию; если вы включаете атрибут, вы должны задать значение по умолчанию. (Поскольку вы можете задать только значение по умолчанию, нет смысла включать в элемент описание атрибута, за исключением желания сделать документ более понятным для восприятия.) Например, следующее объявление присваивает фиксированное значение по умолчанию атрибуту Class:

    <!ATTLIST FILM Class CDATA #FIXED «documentary»>

    В соответствии с этим объявлением следующие два эквивалентных элемента будут корректными:

    <FILM>The Making of XML</FILM>

    <FILM Class=»documentary»>The Making of XML</FILM>

    в то время как следующий элемент будет некорректным:

    <!— Некорректный элемент! —>

    <FILM Class=»instructional»>The Making of XML</FILM>

    Использование внешних подмножеств DTD

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

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

    Примечание. Применение внешнего подмножества DTD имеет смысл главным образом для DTD, которые являются общими для целой группы документов. Каждый документ может ссылаться на один файл DTD (или копию этого файла) как на внешнее подмножество DTD. При этом вам не надо копировать содержимое ВТПв каждый использующий его документ, а также облегчается внесение изменений в DTD. (Вам требуется модифицировать только файл DTD, и все копии этого файла, вместо того, чтобы редактировать все документы, которые его используют.) Как вам известно из главы 1, многие стандартные XML-приложения основаны на общем DTD, включаемом во все XML-документы, отвечающие этому приложению. (См. разделы «Стандартные XML-приложения» и «Реальное использование XML» в главе 1.)

    Использование только внешнего подмножества DTD

    Чтобы использовать только внешнее подмножество DTD, опустите блок объявлений разметки, ограниченных квадратными скобками ([]), и вместо этого включите ключевое слово SYSTEM, после которого в кавычках должно следовать описание местонахождения отдельного файла, содержащего DTD. Рассмотрим, например, документ SIMPLE, используемый ранее в этой главе и имеющий внутреннее подмножество DTD:

    <?xml version-‘1.0″?> 

    <!DOCTYPE SIMPLE

    [

    <!ELEMENT SIMPLE ANY>

    >

    <SIMPLE> This is an extremely simplistic XML document. </SIMPLE>

    Если в этом документе используется внешнее подмножество DTD, он будет иметь следующий вид:

    <?xml version=»1.0″?>

    <!DOCTYPE SIMPLE SYSTEM «Simple.dtd»>

    <SIMPLE> This is an extremely simplistic XML document. </SIMPLE>

    Файл Simple.dtd должен иметь следующее содержимое: 

    <!ELEMENT SIMPLE ANY>

    Файл, содержащий внешнее подмножество DTD, может включать любые объявления разметки, которые могут быть включены во внутреннее подмножество DTD (см. раздел «Создание DTD» ранее в этой главе).

    Описание местонахождения файла (в данном примере Simple.dtd) называется системным литералом. Он может быть заключен в одинарные (‘) или двойные («) кавычки и содержать любые символы, за исключением символов кавычек, используемых как ограничители.

    Системный литерал задает унифицированный идентификатор ресурса (URI — uniform resource identifier) файла, содержащего внешнее подмножество DTD. В настоящее время URI практически аналогичен стандартному Internet-адресу, известному как унифицированный указатель ресурса (URL — Uniform Resource Locator). Вы можете использовать полностью прописанный URI, подобно следующему:

    <!DOCTYPE SIMPLE SYSTEM «http://bogus.com/dtds/Simple.dtd»>

    Или вы можете использовать частичный URI, который задает местонахождение относительно местонахождения XML-документа, содержащего URI, например:

    <!DOCTYPE SIMPLE SYSTEM «Simple.dtd»>

    Примечание. URI представляет собой чрезвычайно гибкую систему нотации для адресации ресурсов. Одним из типов URI является URL (Uniform Resource Locator), обычно используемый в Internet (например, http://mspress.microsoft.com/). В дальнейшем URI будет включать другие типы нотаций для адресации ресурсов. Однако пока они находятся в стадии разработки.

    Относительные URI в XML-документах работают подобно относительным URL в HTML-страницах. Во втором примере, если бы полный URI XML-документа был http://bogus.com/documents/Simple.xml, «Simple.dtd» ссылался бы на http://bogus.com/documents/Simple.dtd. Аналогично, если бы XML-документ был расположен в file:///C:\XML Step by Step\Example, Code\Simple.xml, «Simple.dtd» ссылался бы на file:///C:\XML Step by Step\Example Code\Simple.dtd.

    Использование внешних и внутренних подмножеств DTD одновременно

    Чтобы использовать и внешнее, и внутреннее подмножество DTD, следу-i ‘т использовать ключевое слово SYSTEM вместе с системным литералом, падающим местонахождение файла с внешним подмножеством DTD, после чего внутри квадратных скобок ([]) следует объявление разметки внутреннего подмножества DTD.

    Вот пример простого XML-документа, имеющего как внутреннее, так и ипешнее подмножество DTD:

    <?xmlversion=»1.0″?>

    <!DOCTYPE BOOK SYSTEM «Book.dtd»

    [

    <!ATTUSTBOOK ISBN CDATA «IMPLIED Year CDATA «2000»>

    <!ELEMENT TITLE (#PCDATA}>

    >

    <BOOK Year=»1998″>

    <TITLE>The Scarlet Letter</TITLE> 

    </BOOK>

    Вот содержимое файла Book.dtd, в котором хранится внешнее подмножеcтво DTD:

    <!ELEMENTBOOKANY>

    <!ATTUST BOOK ISBN NMTOKEN #REQUIRED>

    Мели вы используете внешнее и внутреннее подмножество DTD, X ML-процессор объединяет их содержимое следующим образом:

    • в общем случае он осуществляет слияние двух подмножеств, чтобы сформировать полный DTD. В рассмотренном примере объединенный DTD определяет два элемента, TITLE и BOOK, а также два атрибута для элемента BOOK: ISBN и Year,
    • в случае, если атрибут с одним и тем же именем и типом элемента объявляется более одного раза, XML-процессор использует первое объявление и игнорирует все последующие. Это правило применимо и для повторных объявлений примитивов, о чем будет рассказано в главе 6;
    • внутреннее подмножество DTD имеет приоритет перед внешним подмножеством DTD (даже если ссылка на внешнее подмножество идет первой в объявлении типа документа). Таким образом, любой атрибут (или примитив), определенный во внутреннем подмножестве, доминирует над атрибутом с тем же именем и типом элемента, объявленным во внешнем подмножестве. В примере XML-процессор считает, что атрибут ISBN имеет тип CDATA и объявление значения по умолчанию #IMPLIED, поэтому следующий элемент (в котором не указан ISBN) является корректным:

    <BOOKYear=»1850″>

    <TITLE>The Scarlet Letter</TITLE>

    </ВООК>

    Примечание. Хотя XML-процессор просто игнорирует повторные объявления атрибутов и примитивов, повторное объявление элемента (даже если он объявлен тем же самым образом) является допустимым.

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

    Условия игнорирование разделов внешнего подмножества DTD

    Вы можете заставить XML-процессор игнорировать часть внешнего под-мпожггтва DTD с помощью раздела IGNORE. Вы можете, например, использовать раздел IGNORE при разработке документа с целью временного отключения альтернативного или необязательного блока объявлений разметки. При этом вам не нужно удалять строки, а затем повторно их вставлять. (Если вы программист, то вам известно, что такой прием подобен «комментированию» фрагмента кода, который вы хотите временно игнорировать.) Раздел IGNORE начинается с символов <![IGNORE[ и .чаканчивается символами ]]>.

    На следующем рисунке представлен пример полного описания внешнего подмножества DTD, включающего раздел IGNORE.

    Если вы хотите временно восстановить блок объявлений разметки в разделе IGNORE, вам достаточно просто заменить ключевое слово IGNORE на INCLUDE, не удаляя при этом символы-ограничители (<![, [ и ]]>), как и следующем примере:

    <![INCLUDE[

    <!— необязательный блок объявлений разметки,

    который временно восстановлен —> 

    <!ATTLJST BOOK Category CDATA «fiction»> 

    <ELEMENT TITLE (#PCDATA)> 

    <!ELEMENT AUTHOR (#PCDATA)

    ]]>

    Впоследствии вы можете снова быстро отключить раздел, вернув заголовок IGNORE. Раздел INCLUDE, вложенный в раздел IGNORE, также игнорируется.

    Примечание. Вы можете использовать разделы IGNORE и INCLUDE только во внешнем подмножестве DTD либо во внешнем параметрическом примитиве. (Внешний параметрический примитив ссылается на отдельный файл, который — подобно внешнему подмножеству DTD — содержит объявления разметки, подробнее об этом вы узнаете в главе 6.)

    Преобразование корректно сформированного документа в валидный

    В этом разделе вы попытаетесь на практике применить полученные при изучении этой главы знания, преобразовав корректно сформированный документ в валидный. Вы модифицируете документ Inventory.xml, созданный вами в главе 2, чтобы сделать его валидным, а также добавите новый элемент и два атрибута, чтобы освоить описанные в этой главе приемы.

    Сделайте документ валидным

    1. В вашем текстовом редакторе откройте документ Inventory.xml, созданный вами в главе 2. (См. Листинг 2-1 и соответствующий файл на CD-ROM.)
    2. Непосредственно перед элементом Документ — с именем INVENTORY введите следующее объявление типа документа:

    <!DOCTYPE INVENTORY

    [

    <!ELEMENT INVENTORY (BOOK)*>

    <!ELEMENT BOOK (TITLE, AUTHOR, BINDING, PAGES, PRICE)>

    <!ATTLJST BOOK InStock (yes | no) #REQUIRED

    <!ELEMENTTITLE («PCDATA | SUBTITLE)*>

    <!ELEMENT SUBTITLE (#PCDATA)>

    <!ELEMENT AUTHOR (#PCDATA)>

    <!ATTLJST AUTHOR Born CDATA #IMPLIED>

    <! ELEMENT BINDING (#PCDATA)>

    <!ELEMENT PAGES (#PCDATA)>

    <!ELEMENT PRICE (#PCDATA)>

    >

    Совет. При выполнении модификации в ходе данного упражнения вы можете ориентироваться на полностью модифицированный документ, который приведен в Листинге 5-1 в конце этой главы.

    Обратите внимание, что имя следующего за DOCTYPE ключевого слова совпадает с именем элемента Документ, IN VKNTORY, DTD состоит только из внутреннего подмножества, которое определяет элементы и атрибуты документа следующим образом:

    • элемент Документ, INVENTORY, имеет содержимое. Он может включать несколько дочерних элементов BOOK или не включать ни одного;
    • элемент BOOK также имеет содержимое. Оно должно включать строго по одному из следующих элементов, в порядке, перечисленном в объявлении документа: TITLE, AUTHOR, BINDING, PAGES и PRICE;
    • элемент TITLE имеет смешанное содержимое. Он может включать символьные данные с несколькими элементами SUBTITLE или без них;
    • элементы AUTHOR, BINDING, PAGES и PRICE также имеют смешанное содержимое. Эти элементы, однако, могут включать только символьные данные без дочерних элементов;
    • элемент BOOK имеет атрибут нумерованного типа с именем InStock, который является обязательным атрибутом и может принимать значения либо «yes», либо «по»;
    • элемент AUTHOR имеет атрибут строкового типа с именем Born, который является необязательным и не имеет значения по умолчанию.
    1. Добавьте следующий дочерний элемент SUBTITLE в элемент TITLE для книги Moby-Dick:

    <ВООК>

    <TITLE>Moby-Dick

    <SUBTITLE>Or, the Whale</SUBTITLE> 

    </TITLE>

    1. Добавьте обязательный атрибут InStock каждому элементу BOOK, присвоив ему значения «yes» или «по», как показано ниже:

    <ВООК lnStock=»yes»>

    <TITLE>The Adventures of Huckleberry Finn</TITLE>

    <AUTHOR>Mark Twain</AUTHOR>

    <BINDING>mass market paperback</BINDING>

    <PAGES>298</PAGES>

    <PRICE>$5.49</PRICE> 

    </BOOK>

    1. Добавьте необязательный элемент Born к одному или нескольким элементам. Хотя вы можете присвоить этому атрибуту любую синтаксически правильную строку в кавычках, в данном случае он должен хранить дату рождения автора. Пример:

    <AUTHOR Born=»1835″>Mark Twain</AUTHOR>

    1. Чтобы отразить новое имя файла, которое вы собираетесь присвоить, измените комментарий в начале документа с:

    <!— Имя файла: Inventory.xml —>

    на

    <!— Имя файла: Inventory Valid.xml —>

    1. Воспользуйтесь командой Save As (Сохранить как) вашего текстового редактора, чтобы сохранить копию модифицированного документа под именем Inventory Valid.xml.

    Законченный документ представлен в Листинге 5-1. (Копия этого листинга находится на CD-ROM в файле Inventory Valid.xml.)

    Листинг 5-1

    Inventory Valid.xml

    <?xmlversion=»1.0″?>

    <!— Имя файла: Inventory Valid.xml —>

    <!DOCTYPE INVENTORY

    [

    <!ELEMENT INVENTORY (BOOK)*>

    <!ELEMENT BOOK (TITLE, AUTHOR, BINDING, PAGES, PRICE)> 

    <!ATTLIST BOOK InStock (yes|no) #REQUIRED>

    <!ELEMENT TITLE («PCDATA | SUBTITLE)*> 

    <!ELEMENT SUBTITLE (*PCDATA)>

    <!ELEMENT AUTHOR (#PCDATA)> 

    <!ATTLISTAUTHOR BornCDATA #IMPLIED>

    <!ELEMENT BINDING (#PCDATA)> 

    <!ELEMENT PAGES (#PCDATA)>

    <!ELEMENT PRICE (#PCDATA)>

    >

    <INVENTORY>

    <BOOK lnStock=»yes»>

    <TITLE>The Adventures of Huckleberry Finn</TITLE>

    <AUTHOR Born=»1835″>Mark Twain</AUTHOR>

    <BINDING>mass market paperback</BINDING>

    <PAGES>298</PAGES>

    <PRICE>$5.49</PRICE> 

    </BOOK> 

    <BOOK lnStock=»no»>

    <TITLE>Leaves of Grass</TITLE>

    <AUTHOR Born=»1819″>WaltWhitman</AUTHOR>

    <BINDING>hardcover</BINDING>

    <PAGES>462</PAGES>

    <PRICE>$7.75</PRICE> 

    </BOOK> 

    <BOOK lnStock=»yes»>

    <TITLE>The Legend of Sleepy Hollow</TITLE>

    <AUTHOR>Washington lrving</AUTHOR>

    <BINDING>mass market paperback</BINDING>

    <PAGES>98</PAGES>

    <PRICE>$2.95</PRICE> 

    </BOOK> 

    <BOOK lnStock=»yes»>

    <TITLE>The Marble Faun</TITLE>

    <AUTHOR Born=»1804″>Nathaniel Hawthorne</AUTHOR>

    <BINDiNG>tradepaperback</BINDING>

    <PAGES>473</PAGES>

    <PRICE>$10.95</PRICE> 

    </BOOK>

    <BOOK lnStock=»no»> 

    <TITLE>Moby-Dick

    <SUBTITLE>Or, the Whale</SUBTITLE>

    </TITLE>

    <AUTHOR Born=»1819″>Herman Melville</AUTHOR>

    <BINDING>hardcover</BINDING>

    <PAGES>724</PAGES>

    <PRICE>$9.95</PRICE> 

    </BOOK> 

    <BOOK lnStock=»yes»>

    <TITLE>The Portrait of а Lady</TITLE>

    <AUTHOR>Henry James</AUTHOR>

    <BINDING>mass market paperback</BINDING>

    <PAGES>256</PAGES>

    <PRICE>$4.95</PRICE> 

    </BOOK> 

    <BOOK inStock=»yes»>

    <TITLE>The Scarlet Letter</TITLE>

    <AUTHOR>NathanielHawthorne</AUTHOR>

    <BINDING>trade paperback</BINDING>

    <PAGES>253</PAGES>

    <PRICE>$4.25</PRICE> 

    </BOOK> 

    <BOOK lnStock=»no»>

    <TITLE>The Turn of the Screw</TITLE>

    <AUTHOR>Henry James</AUTHOR>

    <BINDING>trade paperback</BINDING>

    <PAGES>384</PAGES>

    <PRICE>$3.35</PRICE> 

    </BOOK> 

    </INVENTORY>

    1. Если вы хотите проверить валидность вашего документа, воспользуйтесь сценарием проверки XML-документа на валидность, приведенным в разделе «Проверка валидности XML-документа» в главе 9.

    Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *