Валидация XML и XHTML

20 октября 2008 года, 19:11

В 105-ом выпуске мы подробно рассмотрели формат DTD: чем является, где применяется и какая польза. На самом деле, эта статья была умышленно сфабрикована для того, чтобы мы смогли идти дальше по валидации разных языков программирования.

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

Общие шаги

Перед тем как переходить к частному, рассмотрим общие шаги на пути к становлению валидации. Для того, чтобы произвести валидацию содержимого, его сначала нужно получить. Источник (то, что мы должны проверить на соответствие набору определённых правил) может быть совершенно непредсказуемым:

  1. Файл;
  2. Строка;
  3. Удалённый источник.

Мы абстрагируемся от указанных выше источников, ведь на самом деле нам не так уж и важно, откуда мы получаем данные для валидации: все они в конечном итоге предстают в виде строки. После того, как мы получили строку, нам нужно её обработать таким образом, чтобы получить элементы, с которыми мы можем работать на том языке программирования, на котором мы программируем. Для начала мы должны определиться, в какие сущности мы можем превратить входные данные. Вспоминаем, что основной единицей в XML/XHTML является элемент. От него и будем отталкиваться. Помимо элемента, нам нужен контейнер элементов, который мы будем называть документом.

Каждый XML/XHTML-документ состоит из набора элементов, причём всегда есть корневой элемент, содержащий в себе все остальные элементы. Постойте! Но ведь это же обычное дерево! Да-да, всё правильно: мы видим перед собой дерево элементов. Мы пришли к достаточно важному выводу: любой XML-документ (и документ на любом XML-подобном языке) можно представить в виде дерева. После, с этим деревом мы можем выполнять самый разный набор операций: сравнение, удаление, перестановка, траверсинг (операция прохода по всем узлам дерева) и другие.

Как проверяется XML

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

  1. Первый элемент в документе — это всегда декларация заголовка XML вида , где […] — атрибуты заголовка XML;
  2. Все элементы должны быть названы верным образом и не должны содержать посторонних символов (пробелов, к примеру);
  3. Все атрибуты должны быть записаны в правильной форме (проверяется достаточно просто, тем же регулярным выражением);
  4. Документ должен содержать только один корневой элемент;
  5. Вложенность элементов должна быть соблюдена (проверка данного утверждения достигается за счёт использования стека элементов, с помощью которого мы проверяем соответствия открывающих и закрывающих элементов);

Примечание: валидатор не должен исправлять ошибки в XML-документах, так как это не входит в его компетенцию.

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

XHTML: лёгкие Интернета

Проверка XHTML основывается на валидации XML. Сначала мы должны удостовериться в том, что документ является валидным с точки зрения XML (то есть соблюдена вложенность тегов, правильно оформлены элементы и их атрибуты, и другие), и уже потом накладывать дополнительные правила. Если документ не является валидным с точки зрения XML, то он заведомо не является валидным и с точки зрения XHTML.

Чтобы применять какие-либо правила XHTML к документу, сначала нужно эти правила описать таким образом, чтобы их было легко получить и как трафарет наложить на документ. Для валидации XHTML-документов правила могут храниться в виде нескольких форматов:

  1. DTD-документы;
  2. XML Schema;
  3. Relax NG.

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

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

После выполнения указанного набора правил можно говорить о том, является ли документ валидным или напротив: содержит какие-то ошибки, которые валидатор может указать пользователю.

Итоги

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

Мнения (10)

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

  • FX Poster

    20 октября 200820:31

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

    Или я чего-то не понимаю, или автор. Как может дерево элементов быть построено до валидации? Приведи пример дерева для следующего документа:

    <?xml version="1.0" encoding="utf-8" ?> <root> <element1> <element2> </element1> </element2> </root>

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

  • Дин

    20 октября 200820:38

    Мы можем дерево построить в любом случае, но вот правильным ли будет это дерево?

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

    В случае возникновения любых ошибок обработки, мы всё равно получим дерево, какое бы оно ни было.

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

  • Miscђka

    21 октября 200810:02

    если у XML указан конкретный DTD, должен ли валидатор с ним сверяться? Если внешний DTD при этом недоступен?

  • Дин

    21 октября 200810:21

    Это зависит от валидатора: на его собственный выбор. Обычно валидаторы XHTML содержат в собственной комплектации все наборы DTD (или иных схем для валидации), а валидаторам XML следует их подгружать, если они указаны.

    XHTML — это, по сути, XML с собственным DTD, но в этом случае валидаторы XHTML не подгружают данные документы из какого-либо удалённого источника (так как считают его ненадёжным).

  • Makishvili

    22 октября 200813:22
    Если все вышеуказанные правила соблюдаются, то документ считается валидным XML-документом

    Разве речь идет о валидации XML-документа? Мне кажется, что правильнее говорить о велформности XML (well-formed).

  • Дин

    22 октября 200813:31

    @Makishvili, в данном случае я считаю, что можно говорить о синонимичности определений. Но это только я считаю: Ваша точка зрения может отличаться от моей.

  • Sannis

    22 октября 200823:04

    @Дин, а как ты называешь валидный документ, который ещё и соответствует своей схеме?

  • Дин

    22 октября 200823:08

    @Sannis, так и называю. Я не развожу понятие о правильности документа, хотя у меня есть понятие Semi-valid. Можете поискать по записям, если интересно. Не понимаю, зачем вводить отдельное понятие well-formed и не использую его.

    Опять же, никому не навязываю это.

  • Sannis

    24 октября 200803:29

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

  • Максим

    02 ноября 200805:55

    Оффтоп — как получить приглашение на ХабраХабр?

Я тоже знаю!

Вы можете тоже написать собственный комментарий. Если хотите к кому-то обратиться, используйте символ @, после которого не забудьте написать имя того, к кому обращаетесь. Не забывайте про существование XHTML-элементов, с помощью которых вы можете оформить ваш комментарий как вам угодно. И, да: ведите себя достойно, вы же не роботы, правда? Если вам интересно, можете подписаться на комментарии по RSS.