В XML::LibXSLT существует возможность обращаться к коду на Perl. Я ни разу не пользовался такой возможностью, поскольку обычно удается решить задачу более простым способом, сформировав все нужные данные до того момента, когда управление будет передано XSLT-процессору.
Тем не менее, интересно посмотреть (и я даже нашел применение), как воспользоваться такой возможностью.
В примере изначально упорядоченные данные из XML-файла выводятся в случайном порядке.
XML имеет такой вид:
<?xml version="1.0"?>
<data>
<item>alpha</item>
<item>beta</item>
<item>gamma</item>
</data>
А XSLT-преобразование — такой:
<?xml version="1.0"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:perl="urn:perl">
<xsl:template match="/data">
<xsl:for-each select="item">
<xsl:sort select="perl:random()"/>
<xsl:value-of select="text()"/>
<xsl:if test="position() != last()">, </xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Здесь выполняется сортировка узлов item в порядке, заданном инструкцией xsl:sort, которая обращается к фукнции perl:random(), которую следует определить и зарегистрировать в парсере XML::LibXML:
use v5.10;
use strict;
use XML::LibXML;
use XML::LibXSLT;
my $xml_parser = new XML::LibXML;
my $xslt_parser = new XML::LibXSLT;
$xslt_parser->register_function('urn:perl', 'random', sub {rand()});
my $document = $xml_parser->parse_file('./data.xml');
my $transform = $xslt_parser->parse_stylesheet_file('./transform.xsl');
my $result = $transform->transform($document);
say $result->toString();
Функция, ссылка на которую указана при вызове register_function, должна возвращать текстовую строку. Имя пространства имен может быть, разумеется, любым, удобным разработчику.
Вывод нескольких последовательных запусков показанного примера в моем случае выглядел так, как и ожидалось (XML-заголовок не показан):
beta, alpha, gamma
gamma, alpha, beta
gamma, alpha, beta
beta, alpha, gamma
beta, gamma, alpha
Ну а смысл? Как только Ты начинаешь делать перловые вставки, - отказываешься от концепта XSLT. А в этом случае гораздо проще (и удобнее) использовать практически все известные шаблонизаторы - TT, HTML::Template, etc...
Фишка-то была в том, чтобы обойтись без перлового функционала. View в своём чистом виде.
Be positive :-)