Устранение неполадок формата документа В мамином списке десятки, если не сотни, рецептов. Если произойдет фатальная ошибка, отладка будет очень сложной — вам придется искать недостающий маркер построчно. Если вы используете несколько уровней вложенности, найти ошибки будет сложно.
Но хорошую помощь можно найти. Парсеры. Приложения, анализирующие XML-код и сообщающие о некорректных ошибках, находятся в свободном доступе в Интернете. Лучшим из них является «Жаворонок», написанный Тимом Бреем — техническим редактором и активным сторонником спецификации XML, одним из умнейших людей на планете.
Я использую Lark для анализа кода ниже. Обратите внимание, что слово «шоколадная крошка» и его закрывающий тег появляются в неправильном положении внутри тега </ingredients>:
<?xml version="1.0"?>
<list>
<recipe>
<author>Carol Schmidt</author>
<recipe_name >Батончики с шоколадной крошкой</recipe_name>
<meal>Ужин
<course>Десерт</course>
</meal>
<ингредиенты>
<item>2/3 стакана сливочного масла</item>
<item>2 стакана коричневого сахара</ item>
<item>1 чайная ложка ванили</item>
<item>1 3/4 стакана непросеянной универсальной муки</item>
<item>1 1/2 чайной ложки разрыхлителя</item>
<item>1/2 чайной ложки соли< /item>
<item>3 яйца</item>
<item>1/2 стакана измельченных орехов</item>
<item>
</ingredients>2 чашки (упаковка по 12 унций) полусладких шоколадных
чипсов</item>. >
<направления>
Разогрейте масло до 350 градусов,
смешайте с коричневым сахароми
ванилью в большой миске,
дайте остыть.
</directions>
</recipe>
</.
Добавьте оставшиеся сухие
ингредиенты, орехи и чипсы.
Выложите в смазанную маслом форму размером 13 на 9 дюймов. Выпекайте 25–30 минут,
пока не остынет.
list>
Ниже приведены результаты, возвращаемые анализатором:
Строкаотчета об ошибках
17, столбец 22: Обнаружено </ingredients> ожидаемое </item>
... предполагаемое </item>
Строка 18, столбец 36: Обнаружено </item> с нет стартового тега.
Имея эту информацию, найти ошибку не составит труда. Так что же означает достоверность XML-файла?
Реализация эффективности В конечном итоге мы добавим информацию в хорошо организованный XML-документ. На самом деле, нам предстоит многое сделать - кризисы все еще подстерегают - и хотя XML-файл хорошо организован,
Но важная информация также может быть потеряна. Взгляните на следующий пример:
<рецепт>
<author>Кэрол Шмидт</author>
<recipe_name>Плитки с шоколадной крошкой</recipe_name>
<meal>Ужин <course>Десерт</course> </meal>
<ингредиенты> </ингредиенты>
<directions>Растопить сливочное масло, смешать с и т. д. ... </directions>
</рецепт>
В этом рецепте не указаны ингредиенты, и поскольку он так хорошо организован,
Анализатор Lark тоже не обнаружит проблему. Любой, кто управлял даже самой безобидной базой данных, знает ошибку, которую совершают мы, люди: если у нас есть такая возможность, мы выбрасываем важную информацию и добавляем бесполезную ерунду. Вот почему изобретатель XML представил DTD —
Определение типа документа. DTD позволяют гарантировать, что XML будет более или менее таким, каким вы хотите его видеть.
Давайте посмотрим на DTD, используемый в рецептах.
<!Список DOCTYPE [
<!ELEMENT рецепт (название_рецепта, автор, блюдо, ингредиенты, инструкция)>
<!ELEMENT ингредиенты (предмет+)>
<!ELEMENT еда (#PCDATA, конечно?)>
<элемент!ELEMENT (#PCDATA, sub_item*)>
<!ELEMENT имя_рецепта (#PCDATA)>
<!ЭЛЕМЕНТ автор (#PCDATA)>
<Курс !ELEMENT (#PCDATA)>
<Элемент!ELEMENT (#PCDATA)>
<Подпункт!ELEMENT (#PCDATA)>
<!ELEMENT направления (#PCDATA)>
]>
Поначалу код может показаться недружелюбным, но он обретает смысл, когда вы его разбираете. Поясним подробнее:
<!DOCTYPE list [
Эта строка говорит о том, что то, что заключено в квадратные скобки, является документом с корневым элементом <list>
ДТД. Как мы упоминали ранее, корневой элемент содержит все остальные элементы.
<!ELEMENT рецепт (название_рецепта, блюдо, ингредиенты, указания)>
Эта строка определяет тег <recipe>. Круглые скобки означают, что четыре тега должны присутствовать в теге <recipe> по порядку.
<!ELEMENT food (#PCDATA, конечно?)>
Эта строка требует подробного пояснения. Я определил следующую структуру:
<meal>Здесь обязательно указывается название еды.
<курс>Может появиться одно название курса, но это не так
обязательно</course>
</еда>
Я делаю это потому, что, по моему мнению, обед не обязательно должен быть конкретным блюдом, но ужин может включать в себя закуски, основные блюда и десерты. Указав
#PCDATA — представляет проанализированные символьные данные (т. е. недвоичные данные) для реализации этой функции. Здесь #PCDATA — это текст, например «ужин».
Знак вопроса после слова «курс» означает, что в теге <еда> появится 0 или 1 пара тегов <курс>.
внутри маркера.
Теперь давайте посмотрим на следующую строку:
<!ELEMENT Ингредиенты (item+)>
Знак «плюс» указывает на то, что в <ingredients> должна присутствовать хотя бы одна пара тегов <item>.
внутри маркера.
Последняя строка, которая нас интересует:
<!ELEMENT item (#PCDATA, sub_item*)>
Я помещаю sub_item* в качестве меры безопасности. Помимо запроса текста каждого элемента, я хочу подсчитать количество контента для каждого элемента. Звездочка указывает количество подэлементов, которые можно включить в тег <item>. Для рецепта батончиков с шоколадной крошкой мне не нужны какие-либо подпункты, но это полезно, когда ингредиенты сложные.
Теперь давайте соберем это вместе и посмотрим, что у нас получится.
Полный пример DTD Ниже приведен полный пример. Я добавил в файл еще один рецепт и добавил
DTD снабжен аннотациями. Вы можете заметить, что во втором рецепте я использовал подпункты.
<?xml версия="1.0"?>
<!--Это запускает DTD. Первые четыре строки адресуют структуру документа-->.
<!Список DOCTYPE ][
<!ELEMENT рецепт (название_рецепта, автор, блюдо, ингредиенты,направление)>
<!ELEMENT ингредиенты (предмет+)>
<!ELEMENT еда (#PCDATA, конечно?)>
<элемент!ELEMENT (#PCDATA, sub_item*)>
<!--Это остальные элементы тега рецепта -->
<!ELEMENT имя_рецепта (#PCDATA)>
<!ЭЛЕМЕНТ автор (#PCDATA)>
<!ELEMENT направления (#PCDATA)>
<!--Оставшийся элемент тега еды -->
<Курс !ELEMENT (#PCDATA)>
<!--Оставшийся элемент тега элемента -->
<!ELEMENT под_элемент (#PCDATA)>
]>
<?xml версия="1.0"?>
<список>
<рецепт>
<author>Кэрол Шмидт</author>
<recipe_name>Плитки с шоколадной крошкой</recipe_name>
<еда>Ужин
<курс>Десерт</course>
</еда>
<ингредиенты>
<item>2/3 стакана сливочного масла</item>
<item>2 стакана коричневого сахара</item>
<item>1 чайная ложка ванили</item>
<item>1 3/4 стакана непросеянной муки общего назначения</item>
<item>1 1/2 чайной ложки разрыхлителя</item>
<item>1/2 чайной ложки соли</item>
<item>3 яйца</item>
<item>1/2 стакана измельченных орехов</item>
<item>2 чашки (упаковка по 12 унций) чипсов полусладкого шоколада</item>
</ингредиенты>
<направления>
Разогрейте духовку до 350 градусов.
смешайте с коричневым сахаром и ванилью в большой миске.
Отставьте в сторону, чтобы остыть. Смешайте муку, разрыхлитель и соль;
отложите в сторону. Добавьте яйца в остывшую сахарную смесь и хорошо взбейте;
Добавьте сохраненные сухие ингредиенты, орехи и чипсы.
Выложите в смазанную маслом форму размером 13 на 9 дюймов.
Выпекайте 25–30 минут до золотистого цвета;
Разрезать на квадраты.
</направления>
</рецепт>
<рецепт>
<recipe_name>Паста с томатным соусом</recipe_name>
<еда>Ужин
<курс>Входное</курс>
</еда>
<ингредиенты>
<item>1 фунт спагетти</item>
<item>1 банка нарезанных кубиками помидоров весом 16 унций</item>
<item>4 зубчика чеснока</item>
<item>1 нарезанная кубиками лук</item>
<item>Итальянская приправа
<sub_item>орегано</sub_item>
<sub_item>базилик</sub_item>
<sub_item>молотый красный перец</sub_item>
</item>
</ингредиенты>
<направления>
Отварить макароны. Обжарить чеснок и лук.
Добавьте помидоры. Подавайте горячими.
</направления>
</рецепт>
</список>
Теперь, когда существует DTD, документ будет проверен на соответствие ограничениям, установленным DTD. Другими словами, мы хотим обеспечить действительность документа.
Чтобы добиться этого, нам нужен еще один инструмент: анализатор достоверности. MSXML от Microsoft, программа на основе Java, проста в использовании и хорошо работает. Вышеуказанный документ был проверен этой программой и ошибок не обнаружено. Но если я проверю
Рецепты, которые не содержат элемент в теге ингредиента, вернут следующее сообщение: «
Ожидаемые элементы [элемент] не завершены».