![]() |
| Extension elements and functions The extension instructions are loaded in the namespace of XSLT package. We design XSLT package in procedural style. The XSL instruction is a Perl function that has the name of XML element with symbols ':' and '-' replaced by underscore symbol '_'. The processor executes it at compile time. The extension function must return the reference to the function that will do the real job. The name prefix is required. package XSLT;
use strict;
my $local_var='';
$XSLT::global_var='';
sub prefix_top_element {
my $xslt_top_node=shift;
#initialize variables
$local_var='hello';
$XSLT::global_var='world';
#prevent execution of the top instruction in the XSLT code
return \&_do_nothing;
}
sub prefix_instruction_name {
my $xslt_tree_node=shift;
#compilation code here
return \&_prefix_instruction_name;
}
sub _prefix_instruction_name {
my ($xslt_tree_node,$xml_source_current_node,$result_tree_node)=@_;
#execution code
}
sub prefix_FINISH {
#reinit variables here for compatibility with mod_perl
$local_var='';
$XSLT::global_var='';
#do not use exit or die!
#this function is not required
}
1;All variables with the word "node" in their names are objects of XMLTree class. The extension functions are loaded in the namespace of XPath::Expression package designed in object oriented style. The function is the method of XPath::Expression class that has the name of the extension function with ':' and '-' replaced by '_'. The name prefix is recommended. package XPath::Expression;
use strict;
sub prefix_function_name {
my ($expr,$current_node,$retern_type)=@_;
my $args=$expr->{arg} || die "the function needs arguments";
# $args is a ref to array of XPath::Expression objects
#the evaluate method return the result as it is
my @evaled_args=map{$_->evaluate($current_node)} @{$args};
#the string method converts the result to scalar type
my @evaled_string_args=map{$_->string($current_node)} @{$args};
#wish to retun a scalar
return $my_scalar_var;
#wish to return a result tree fragment
my $new_tree=$current_node->newroot();
#create tree code
#convert it to node-set
my $ns=[$new_tree];
#evaluate step operators and conditions if they are present
return $expr->proceed($ns);
}
1;The parameter $return_type indicates the context of the extension function. It is needed only if you want to create the function return value of which depends on the expression context. Example is the gmtime function built in the XSLT processor. Declarations of extension instructions and functions can be placed in the same file. The XSLT stylesheet loads it as follows <xsl:stylesheet xmlns:prefix="#path-to-module/my-module.pm"> .... </xsl:stylesheet> Functions used for compilation of XSLT elements The attributes of XSLT instruction can be attribute templates and XPath expressions. Both types require compilation. sub prefix_instruction {
my $xslt_element=shift;
$atr=$xslt_element->getAttribute('name-of-it');
#logic for error handling die if it is critical
$xslt_element->{prefix_compiled_value}=compile_attr_expr($atr);
$xatr=$xslt_element->getAttribute('xpath-attr');
$xslt_element->{prefix_compiled_xpath}=XPath::Expression->parse($xatr)||die $XPath::Vars::Error;
#code
return \&_prefix_instruction;
}
sub _prefix_instruction {
my ($xslt_element,$xml_source_current_node,$result_tree_node)=@_;
my $atr=$xslt_element->{prefix_compiled_value};
#get value
my $atrval=eval_attr_expr($atr,$xml_source_current_node);
my $xp=$xslt_element->{prefix_compiled_xpath};
my $xpresult=$xp->evaluate($xml_source_current_node);
#create new tree fragment example
my $newtree=$xml_source_current_node->newroot();
if(ref($xpresult)) { #check that we have node-set
foreach my $n (@{$xpresult}){
eval_template($xslt_element,$n,$newtree);
}
}
#analize $newtree
#print something to result tree
$result_tree_node->newchild('test')->newtext($atrval);
} |