xmlhack.ru logo
>> статьи на xmlhack.ru

Экранированная разметка вредна

Автор: Норман Уолш
Перевод: А.Скробов
Опубликовано на XML.com (20.09.2003, англ.): http://www.xml.com/pub/a/2003/08/20/embedded.html
Опубликовано на xmlhack.ru (25.02.2006, рус.): http://xmlhack.ru/texts/06/escaped-markup/escaped-markup.html
В закладки:   Del.icio.us   reddit

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

Недавно я столкнулся с шаблоном (а скорее, даже анти-шаблоном), который угрожает всему тому, на чём построены наши проекты. Он вреден, и его необходимо искоренить.

Краткая историческая справка

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

Технические преимущества синтаксической корректности очевидны: она позволяет парсеру просто и однозначно определить логическую структуру XML-документа. XML пришёл на смену SGML — языку с кучей правил для сокращения объёма разметки. Из-за всех этих правил написать парсер для SGML было тяжело — причём очень тяжело. Ещё у SGML был «двоюродный брат» — HTML. Большая часть HTML-документов не удовлетворяла даже правилам SGML; чтобы обрабатывать HTML, приложениям приходилось — кроме всей сложности работы с SGML — изобретать на ходу собственные правила обработки некорректной разметки.

У всех этих языков, кошмарных с точки зрения написания парсеров и неоднозначности разметки, было одно преимущество: разметка документов вручную была чрезвычайно проста. SGML позволял не заключать значения атрибутов в кавычки, опускать открывающие или закрывающие теги, и — при желании — пользоваться чудным мини-языком SHORTREF. HTML позволял загрузить в браузер практически любую мешанину тегов — и браузер показывал нечто осмысленное. Если чуть-чуть поколдовать над этой мешаниной тегов, то можно было даже получить результат, который — в некоторых браузерах — соответствовал задуманному.

XML объявил: «Не пойдёт. Слишком тяжело, слишком дорого, слишком сложно. Ваша разметка должна выглядеть вот таким вот образом — практически без сокращений. И если хоть что-то в ней будет неверно, то приложения не имеют права каким-либо образом обрабатывать ваши ошибки. Если документ синтаксически некорректен, то это не XML

Тогда мы все на минутку затаили дыхание.

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

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

И всё это благодаря тому, что XML-документы обязаны быть синтаксически корректными.

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

Моё удивление сменилось недоумением, когда я узнал, что разработчики новой версии RSS не собираются исключать из него этот безобразный хак. Когда же я узнал, что этот хак проник в другой XML-язык — FOAF — то моё недоумение сменилось крайней озабоченностью.

Что такое экранированная разметка?

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

В RSS экранированная разметка обычно выглядит так:

<description><![CDATA[
Some description of an article about
<a href="http://www.w3.org/TR/REC-xml">XML</a> that
contains a link and a <br> element.]]>
</description>

Важно понимать, что этот пример мог бы быть записан и по-другому:

<description>
Some description of an article about
&lt;a href="http://www.w3.org/TR/REC-xml"&gt;XML&lt;/a&gt; that
contains a link and a &lt;br&gt; element.
</description>

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

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

Some description of an article about <a href="http://www.w3.org/TR/REC-xml">XML</a> that contains a link and a <br /> element.

Но по совершенно непостижимым причинам большинство RSS-клиентов отобразит его так:

Some description of an article about XML that contains a link and a
element.

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

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

По-видимому, есть два аргумента в защиту экранированной разметки:

  1. Агрегаторы используют средства XML для объединения данных из нескольких RSS-источников («фидов»). Агрегаторы — это программы либо сайты, которые могут составлять для нескольких источников единый RSS-фид. Можно, например, подписаться на фид, отображающий последние десять новостей, переданные выбранными вами агентствами.

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

    Я не думаю, что эти аргументы сколько-нибудь оправдывают выбранную агрегаторами стратегию:

    1. Экранирования разметки, особенно при помощи секций CDATA, недостаточно, чтобы получился синтаксически корректный XML-документ. Есть и другие вещи, способные нарушить синтаксическую корректность: запрещённые символы Unicode, проблемы кодировки для допустимых символов Unicode, запрещённые последовательности символов (такие как «[[>») и т.д. Не говоря уже о том, что вложенные секции CDATA недопустимы.

    2. Есть более простые способы экранирования содержимого. Прежде всего, если само это содержимое — синтаксически корректный XML, то не требуется никакого экранирования. Если это не синтаксически корректный XML, то скорее всего, это HTML. Даже и в этом случае запрещено выдавать за XML документ, не являющийся синтаксически корректным. Известно много способов преобразовать HTML-документ в XHTML (или даже просто в синтаксически корректный XML). Самый простой из этих способов — полное отбрасывание всей HTML-разметки — и то лучше, чем «решение» с экранированием разметки.

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

    3. Если так уж необходимо экранировать содержимое, если слишком непрактично преобразовывать его в синтаксически корректный XML либо слишком накладно обрабатывать его вложенную разметку — тогда кодируйте содержимое в base64.

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

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

  2. Экранирование разметки позволяет помещать HTML-код и другую разметку внутрь элементов, в которых XML-схема или DTD допускает только простой текст.

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

Экранированная разметка вредна

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

А похоже, что этот хак уже расходится. Не так давно вопрос экранированной разметки всплыл в контексте FOAF. Спецификация FOAF не допускает никаких подобных хаков, но одна из программ для блоггеров, генерирующая FOAF, после вставки пользователем HTML-кода в элемент «bio» экранировала в нём всю разметку. Фирму-разработчика этой программы быстро удалось убедить исправить этот баг.

Экранированную разметку необходимо искоренить

Совершенно ясно, что шаблон экранированной разметки разойдётся по XML-языкам, если это не пресечь. Если не удастся остановить его вовремя, то он станет стандартом де-факто, и разработчики будут вынуждены продолжать поддержку этой мерзости из простых экономических соображений. И виноваты будут не они, а все мы — в том, что не убили вирус до того, как он заразил всё вокруг.

Дополнения к статье



XML.com Copyright © 1998-2007 O'Reilly Media, Inc.
Перевод: xmlhack.ru Copyright © 2000-2007 xmlhack.ru