to post messages and comments.

Событие DOMContentLoaded до сих пор не происходит в Firefox для получившегося после XSLT документа что ли? Ну что за люди… Сижу втыкаю в код, а оно, оказывается, просто не работает. Ну офигеть теперь.

bugzilla.mozilla.org
Reported: 2006-02-04
ШЁЛ 2013 ГОД…

Декомпозиция сущностей привела к тому, что для того чтобы сделать трансформацию xslt-шаблона страницы нужно подгрузить 10-20 внешних xslt, которые подгружаются через xsl:import. Это привело к долгой загрузке шаблона для его трансформации. Конструкция
$proc = new XSLTProcessor();
$proc->importStyleSheet($xsl);
могла занимать 3 секунды.

От декомпозиции отказываться не хотелось. Уж очень мне нравится идея сделать так
<xsl:call-template name="m_users_show_link"/>
а потом всего в одном месте править, чтобы выводить везде на сайте ФИО или И.О.Ф. В общем много плюшек имеем с этого.

В #2393013 была попытка решить вопрос использованием xsltCache. Но он работает странно. У него долго происходит не только первая загрузка, но и 2,3,4, а потом если повезёт то загрузит шаблон быстро. Не понял я отчего он так себя ведёт.

Там же в #2393013 я высказал идею парсить xsl в единый файл со всеми необходимыми шаблонами и уже без импортов. Сначала я решил сделать это регулярками. Идея показала свою жизнеспособность и возможность такого преобразования. Но идея делать это регулярками не очень хороша, по кучи причин, одна из которых в том, что php иногда валился с неопознаной ошибкой.

Сегодня ночью был реализован вариант с разбором xsl через представление его в виде xml-дерева. В итоге получилось объединить (скомпилировать) необходимые xslt-шаблоны в один за разумное время с последующим его сохранением на диск.
Бенчмарки трансформаций
— некомпиленый вариант — 3.3 сек.
— первая компиляция — 1.1 сек.
— использование уже скомпиленого шаблона — 0.08 сек.
— с включённым xsltcache с использованием скомпиленого шаблона — 0.03 сек.

Как видно, даже вариант "скомпилить все xsl файлы в один, а потом сделать трансформацию" работает в 3 раза быстрее, чем просто "сделать трансформацию на шаблоне с кучей импортов". Не говоря уже о трансформации закешированого скомпиленого шаблона.

А ещё я люблю использовать именованные шаблоны вместо матчей. Т.е. я использую <xsl:template name="m_user"> вместо <xsl:template match="user">. И это дало положительный эффект. После сборки единого xsl-файла, парсер пробегается по нему и ищет, какие именнованые шаблоны вызываются (<xsl:call-template name="..."/>). А затем все неиспользуемые темплейты попросту выбрасываются. Если бы в коде использовались матчи, то невозможно было бы определить вызывется ли этот шаблон или нет, потому что данных ещё нет. Такое выбрасывание ненужных шаблонов уменьшило размер скомпиленого xsl-файла на 30%.

Вот уж не ожидал, но xsltCache нехило так ускоряет импорт xsl файлов.
Есть в проекте разухабистый xsl с кучей импортов (подозреваю что импорты — узкое место) и он импортируется на моей тачке безумные 2 секунды.

$xsl = new DomDocument();
$xsl->load($xsl_file_path);
$proc = new XSLTProcessor();
$proc->importStyleSheet($xsl); //2!!! секунды

Проблема в том, что результат importStyleSheet невозможно закешировать. После установки xsltCache код стал таким

if (class_exists("xsltcache", false)){
$proc = new xsltCache();
$proc->importStyleSheet($xsl_file_path);
}
else{
$xsl = new DomDocument();
$xsl->load($xsl_file_path);

$proc = new XSLTProcessor();
$proc->importStyleSheet($xsl);
}

И импорт стал работать 0.0001 секунды.

Проект pecl.php.net
Установка на php5.4 michaelsanford.com
Расширение xslcache.so нужно загружать после xsl.so, иначе PHP может падать (segmentation fault)
И ещё годная заминусованя статья на хабре habrahabr.ru
В сети упоминается что расширение xslcache достаточно стабильно. Некоторые рекомендуют использовать на боевых серверах.

PS На счёт импортов. Может есть смысл парсить xsl, заменять строки импорта на сами импортируемые файлы и сохранять? Тогда у нас получится один большой xsl файл, но уже без всяких зависимостей. Нужно будет как-нибудь потестить.

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

<xsl:template name="bitmask">
<xsl:param name="value" />
<xsl:param name="mask" />

<xsl:if test="(($value mod ($mask * 2)) — ($value mod $mask)) = $mask">
<!-- если маска содержится -->
</xsl:if>
</xsl:template>

Прикольный баг в модуле xslt для нгинкса :) Тег "<br />" разворачивается в "<br></br>", что некоторыми браузерами интерпретируется как двойной брейк. Мелочь, конечно, но как-то в тупик ставит — не ясно, как обойти :)

Тут совершенно внезапно выяснил, что прекрасный нгинкс умеет прекраснейшим образом обхуячивать xsl для вывода с прокси. Был крайне сильно удивлен, даже я бы сказал — охуел. Это ж можно весь трансформинг с апп-сервера на нгинкс повесить. Пиздец, пол-жизни мимо.

а умеет ли оно сделать несколько файлов на выходе — у меня на фходе формат где может быть много нод — а на выходе- только одна? чтото я торможу

xsl. Как в результирующем дереве предку текущего узла добавить атрибут?

Что-то вроде
<xsl:attribute name=""></xsl:attribute>
но только для предка текущего узла.