fdik.org
YSLT — XSLT C style
Ссылка на YBlog2 битая, правильная — auchdieserschwachsinnmussinsinternet.de
А вообще я смотрел на этот проект: beremiz.org
YSLT — XSLT C style
Ссылка на YBlog2 битая, правильная — auchdieserschwachsinnmussinsinternet.de
А вообще я смотрел на этот проект: beremiz.org
$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%.
Есть в проекте разухабистый 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 файл, но уже без всяких зависимостей. Нужно будет как-нибудь потестить.
<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>
fas.harvard.edu . Хочу, чтобы в нашей стране в ВУЗах такое делали.
В iTunesU нашел совершенно чудесные лекции про XML и Java от Стенфордского университета Что-то вроде
<xsl:attribute name=""></xsl:attribute>
но только для предка текущего узла.