Преобразование узлов HTML с помощью XSLT в chrome / webkit - PullRequest
2 голосов
/ 08 августа 2011

Я хочу преобразовать узлы HTML со страницы XHTML с помощью таблицы стилей XSL.

вот функция, которую я использую:

function XSLT(xml,xsl) {
        var tmpElt = document.createElement("div");

        if (window.ActiveXObject){
            //Version IE
            tmpElt.innerHTML = xml.transformNode(xsl);
        }else{
            //Version ECMA
            var xsltProcessor = new XSLTProcessor();
            xsltProcessor.importStylesheet(xsl);
            var result = xsltProcessor.transformToFragment(xml, document);

            var serializer = new XMLSerializer();
            var str = serializer.serializeToString( result );

            tmpElt.innerHTML = str;
        }

        return tmpElt;
}

это будет работать на chrome, если xml не является HTMLElement. именно эта строка:

var result = xsltProcessor.transformToFragment(xml, document);

возвращает ноль для хрома [большую часть времени]. На Firefox он ведет себя правильно.


Я пробовал этот обходной путь:

  • сериализация xml с externalHTML (и даже с XMLSerializer :: serializeToString ())
  • Разобрать его с помощью нового DOMParser ()
  • XSLT результат

но, к сожалению, outerHTML и innerHTML не будут генерировать правильный XHTML и не будут отображать действительный XML (он не будет закрывать отдельные теги, такие как <hr />). XMLSerializer также не будет закрывать отдельные теги, что довольно удивительно для меня.


Я заметил, что преобразования узлов HTML будут работать исключительно, когда фактический HTML не содержит самозакрывающихся тегов. Поэтому я предполагаю, что Chrome внутренне сериализует HTML с XMLSerializer или outerHTML до XSLT.

Вот JSFiddle: http://jsfiddle.net/eVbv7/

Итак, как я могу XSLT HTML-узлы в Chrome? Мне нужен либо способ для правильной сериализации узлов XHTML, либо подойдет любой обходной путь.

Ответы [ 3 ]

4 голосов
/ 09 августа 2011

Я снова обдумал проблему и затем подумал, может ли вам не потребоваться пользовательское клонирование или сериализация для Chrome или Webkit, если вы просто создадите фиктивный документ XML DOM и затем импортируете элемент из документа HTML DOM. Поэтому я написал http://jsfiddle.net/5TNH9/, и действительно, как Chrome 13, так и Safari 5.1, по крайней мере, выполняют преобразование. Так что это может быть другой вариант, чтобы избежать реализации сериализации или полного клонирования с вашим собственным кодом скрипта.

Обратите внимание, что в этом тестовом примере на jsfiddle и в Chrome, и в Safari обнаружена проблема с дублированными элементами br, которая отсутствует в Mozilla или Opera. В настоящее время я не могу сказать, является ли эта проблема общей с выбранным мною подходом или что-то конкретное для этого небольшого контрольного примера.

3 голосов
/ 07 ноября 2012

Еще одна вещь, о которой следует помнить, это то, что атрибут "id" должен быть уникальным.Простая передача некоторого HTML через xsl: copy приведет к дублированию (см., Например, результат Martin's jsfiddle ):

<div id="d1">
    <h2 align="center">Test</h2>
    <p>This is a test.<br>
        This is a test.<br>
        This is a test.
    </p>
</div>
<div xmlns="http://www.w3.org/1999/xhtml" id="d1">
    <h2 align="center">Test</h2>
    <p>This is a test.<br><br>
        This is a test.<br><br>
        This is a test.
    </p>
</div>

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

1 голос
/ 08 августа 2011

Я думаю, что Chrome и Safari могут делать то, что вы хотите, если узлы XHTML являются частью документа, анализируемого с помощью синтаксического анализатора XML, что означает, что если вы используете исходный документ, который вы используете как application / xhtml + xml вместо text / html, тогда выможет применять XSLT к элементам XHTML.Конечно, это исключает любую версию IE, кроме IE 9, если только вы не можете выполнить согласование содержимого на сервере для предоставления текста / html старым версиям IE и application / xhtml + xml другим браузерам.

Еслиузлы, которые вы хотите преобразовать, являются частью документа, анализируемого как text / html, тогда я пока не знаю решения, кроме написания собственного кода для сериализации по мере необходимости в соответствии с правилами XML или написания собственного кода, клонирующего узлы HTML DOMв X (HT) ML DOM-узлы, которые вы можете передать в transformToFragment.

Я знаю, что этот ответ не решает вашу проблему напрямую, но основан на комментариях, когда ранее сообщалось о несовместимости, такой как https://bugs.webkit.org/show_bug.cgi?id=53375, о которой сообщалосьне думаю, что это легко исправить.Кажется, что WebKit проделывает некоторую тяжелую работу, с одной стороны, пытаясь реализовать API-интерфейс Mozilla XSLTProcessor, с другой стороны, обеспечивая libxslt в качестве своего XSLT-процессора, что приводит к нескольким несовместимостям.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...