Всем привет! Те, кто активно использует XSLT для генерации HTML (не XHTML), вероятно, часто сталкивались с ситуациями, когда для генерации валидного HTML необходимо генерировать не только валидный XML — XHTML, но и для браузеров, не поддерживающих XHTML. это не то же самое.
Для этого мы использовали «грязные хаки» в XSLT. В этом посте я расскажу о более чистом и красивом методе, который, к сожалению, используется не часто.
Этот метод специфичен для платформы .
Net, но другие платформы, вероятно, имеют аналогичные инструменты.
Ну а теперь по порядку.
Введение
Понятно, что представления информации XML достаточно для описания любого HTML-документа, и, более того, оно прекрасно вписывается в структуру XML. Проблема в том, что текстовое представление XML может отличаться от представления HTML того же документа.
Суть проблемы
Критические отличия сериализации XML от HTML довольно просты:- В документе не может быть объявлений XML. ;
- Некоторые элементы должны иметь закрывающий тег.
, что означает, что стандартный сериализатор XML неправильно выполнит самозакрывающийся тег для пустого div, т.к.
парсер HTML должен ожидать закрывающий тег для div;
- некоторые элементы не могут содержать ссылки на сущности , что означает, что анализатор HTML не обрабатывает ссылки на сущности в таких элементах, как скрипт или стиль.
- Некоторые элементы могут не иметь содержимого , т.е.
должен быть пустым; например, для элемента ссылки не допускается содержание контента, и поэтому, если для ссылки она даже не имеет контента, а имеет отдельный закрывающий тег, то это будет ошибкой в парсере HTML (что, конечно, и есть проигнорирует);
- некоторые элементы не могут содержать дочерние элементы или комментарии , это такие элементы, как title и textarea;
- общие ограничения структуры документа , которые мы здесь рассматривать не будем, а оставим пытливым умам =)
Сам метод
Дело в том, что окружающая среда использует XmlWriter , который берет на себя всю работу по правильному форматированию XML. Этот класс используется практически во всех операциях, где вам нужно каким-либо образом записать XML. В частности, с преобразованиями XSL ( XslCompiledTransform.Transform ), экземпляр этого класса используется в качестве места назначения.
Итак, все, что вам нужно, это реализовать свой собственный XmlWriter, который будет корректно форматировать наш XML в соответствии с правилами HTML. Итак, представим - HtmlXmlWriter !
Теория
Давайте возьмем спецификацию HTML, а точнее HTML5 (где бы мы сейчас были без нее), и посмотрим, что в ней есть? Существует 5 типов элементов.:
- Пустотные элементы - область, база, br, col, команда, встраивание, час, img, ввод, генератор ключей, ссылка, мета, параметр, источник;
- необработанные текстовые элементы — сценарий, стиль;
- Элементы RCDATA (только текст) - текстовая область, заголовок;
- чужеродные (внешние) элементы — любые внешние элементы, не относящиеся к HTML, в частности из MathML и SVG, но мы будем считать таковыми любые элементы не из пространства имен XHTML;
- нормальные элементы — все остальные элементы HTML;
Я сделал это для себя, и возможно, когда задокументирую, а если меня слезно попросят, то выложу в какой-нибудь репозиторий кода.
Здесь я буду давать только полезные замечания (возможно, немного сумбурные).
HtmlXmlWriter станет преемником XmlWriter. Он должен агрегировать сторонний экземпляр XmlWriter (который необходимо передать конструктору) и по умолчанию вызывать из него соответствующие методы.
HtmlXmlWriter должен отслеживать, в каком элементе он находится в данный момент (имя и тип последнего элемента), определяя это в методе XmlWriter.WriteStartElement /Вритеендэлемент. Он также должен отслеживать, присутствует ли он в атрибуте (WriteStartAttribute/WriteEndAttribute).
При закрытии элемента (WriteEndElement/WriteFullEndElement) выберите, в зависимости от типа элемента, использование WriteEndElement или WriteFullEndElement. Сложнее всего обстоят дела с необработанными текстовыми элементами, поскольку XmlWriter экранирует некоторые символы.
Поэтому необходимо заменить вывод текста на них (WriteCharEntity, WriteString, WriteSurrogateCharEntity) на WriteRaw. Но здесь надо не забыть следить за тем, чтобы в тексте не было закрывающего тега.
Заключение
Теперь имея такой класс, вы можете легко передать его в XSL-преобразования (или куда-либо еще) и получить из XHTML нормальный HTML, так что его поймет даже любой тупой парсер HTML. Теги: #xhtml #xml #HTML #html5 #.NET #xmlwriter #htmlxmlwriter #.
NET
-
Пласкетт, Джон Стэнли
19 Oct, 24 -
Google Reader: Цифры И Факты.
19 Oct, 24 -
Канобувости 13 Выпуск
19 Oct, 24