diff options
author | dakkar <dakkar@sardina.(none)> | 2009-04-30 21:50:05 +0200 |
---|---|---|
committer | dakkar <dakkar@sardina.(none)> | 2009-04-30 21:50:05 +0200 |
commit | a2ad1449e5f0fa52c03c486966131b5528f2a04a (patch) | |
tree | 37037ff63bc337e374481c6033e07b022c1ffec6 /lib/Tree/Transform/XSLTish/Transformer.pm | |
parent | added a prerq I had forgotten (diff) | |
parent | better perl version requirements (diff) | |
download | Tree-Transform-XSLTish-a2ad1449e5f0fa52c03c486966131b5528f2a04a.tar.gz Tree-Transform-XSLTish-a2ad1449e5f0fa52c03c486966131b5528f2a04a.tar.bz2 Tree-Transform-XSLTish-a2ad1449e5f0fa52c03c486966131b5528f2a04a.zip |
Merge branch 'master' of git@luxion:Tree-Transform-XSLTish
Conflicts:
Makefile.PL
Diffstat (limited to 'lib/Tree/Transform/XSLTish/Transformer.pm')
-rw-r--r-- | lib/Tree/Transform/XSLTish/Transformer.pm | 142 |
1 files changed, 128 insertions, 14 deletions
diff --git a/lib/Tree/Transform/XSLTish/Transformer.pm b/lib/Tree/Transform/XSLTish/Transformer.pm index fd61ea6..a36bd6a 100644 --- a/lib/Tree/Transform/XSLTish/Transformer.pm +++ b/lib/Tree/Transform/XSLTish/Transformer.pm @@ -8,14 +8,12 @@ use Tree::Transform::XSLTish::Context; use Tree::XPathEngine; use Carp::Clan qw(^Tree::Transform::XSLTish); +our $VERSION='0.2'; + subtype 'Tree::Transform::XSLTish::Engine' => as 'Object' => where { - my $object=$_; - for my $meth (qw(findnodes)) { - return unless $object->can($meth); - } - return 1; + return $_->can('findnodes') ? 1 : (); }; has 'rules_package' => (is => 'ro', isa => 'ClassName'); @@ -44,15 +42,15 @@ sub _build_engine { my ($self)=@_; if ($self->rules_package) { - my $factory=Tree::Transform::XSLTish::Utils::_engine_factory($self->rules_package); - if ($$factory) { - return $$factory->(); + my $factory=$self->rules_package->can($Tree::Transform::XSLTish::Utils::ENGINE_FACTORY_NAME); + if ($factory) { + return $factory->(); } } return Tree::XPathEngine->new(); } -sub it { $_[0]->context->current_node } +sub it { return $_[0]->context->current_node } sub transform { my ($self,$tree)=@_; @@ -115,7 +113,7 @@ sub find_rule { return $ret if $ret; } - croak "No valid rule"; + croak 'No valid rule'; } sub find_rule_by_name { @@ -140,16 +138,18 @@ sub find_rule_in_package { my $rules=$store->{by_match}; my @candidates= - sort { $b->{priority} <=> $a->{priority} } - grep { $self->rule_matches($_) } @$rules; + sort { $b->{priority} <=> $a->{priority} } ## no critic (ProhibitReverseSortBlock) + grep { $self->rule_matches($_) } @{$rules}; if (@candidates > 1 and $candidates[0]->{priority} == $candidates[1]->{priority}) { - croak "Ambiguous rule application"; + croak 'Ambiguous rule application'; } elsif (@candidates >= 1) { return $candidates[0]; } + + return; } sub find_rule_by_name_in_package { @@ -200,7 +200,7 @@ sub rule_matches { __PACKAGE__->meta->make_immutable;no Moose; -package Tree::Transform::XSLTish::ContextGuard; +package Tree::Transform::XSLTish::ContextGuard; ## no critic (ProhibitMultiplePackages) sub new { my ($class,$trans,$context)=@_; @@ -210,7 +210,121 @@ sub new { sub DESTROY { $_[0]->{trans}->leave(); + return; } 1; __END__ + +=head1 NAME + +Tree::Transform::XSLTish::Transformer - transformer class for L<Tree::Transform::XSLTish> + +=head1 METHODS + +=head2 C<new> + + $trans=Tree::Transform::XSLTish::Transformer->new( + rules_package => 'Some::Package', + engine => $engine_instance, + ); + +You usually don't call this constructor directly, but instead use L<< +the C<new> function exported by +Tree::Transform::XSLTish|Tree::Transform::XSLTish/new >>, which passes +the correct C<rules_package> automatically. + +If you don't specify an C<engine>, it will be constructed using the +class or factory declared in the rules package; if you didn't declare +anything, it will be an instance of L<Tree::XPathEngine>. + +=head2 C<transform> + + @results=$trans->transform($tree); + +When you call this function on a tree, the transformer will transform +it according to your rules and to the L<XSLT processing +model|http://www.w3.org/TR/xslt.html#section-Processing-Model>. + +C<< $trans->transform($node) >> is equivalent to C<< +$trans->apply_rules($trans->engine->findnodes('/',$node)) >>. + +Always call this method in list context. + +=head2 C<apply_rules> + + $trans->apply_rules(@nodes); + +Just like C<apply-rules> in XSLT, this function will apply the rules +to the specified nodes, or to the children of the current node if none +are passed, and return all the results in a single list. + +This will die if there are no matching rules, or if there are more +than one matching rule with highest priority. + +Always call this method in list context. + +=head2 C<call_rule> + + $trans->call_rule('rule-name'); + +This fuction will apply the named rule to the current node, and return +the result. + +This will die if there is no rule with the given name. + +Always call this method in list context. + +=head2 C<it> + + $current_node = $trans->it; + +Inside a rule, this fuction will return the node to which the rule is +being applied. + +=head1 INTERNAL FUNCTIONS + +These functions should not be called from outside this module. + +=head2 C<find_rule> + +For each package in the linearized inheritance chain of the rules +package on which this transformer has been instantiated, calls +L<find_rule_in_package> and returns the first defined result. + +=head2 C<find_rule_in_package> + +Gets all the rules having a C<match> attribute, filters those for +which L<rule_matches> returns true, sorts them priority, and returns +the one with the highest priority. + +Dies if there is more than one rule with the highest priority; returns +undef if there are no matching rules. + +=head2 C<find_rule_by_name> + +For each package in the linearized inheritance chain of the rules +package on which this transformer has been instantiated, calls +L<find_rule_by_name_in_package> and returns the first defined result. + +=head2 C<find_rule_by_name_in_package> + +Returns the rule with the given name, if any; returns undef otherwise. + +=head2 C<rule_matches> + +Evaluates the C<match> XPath expression in a sequence of contexts, to +see if the current node appears in the resulting node-set. If it does, +returns true; if there is no such context, returns false. + +The first context is the current node; following contexts are each the +parent node of the previous one. + +NOTE: to check whether a node appears in a node-set, we either use the +C<isSameNode> method, or check the stringifications for equality. + +=head1 AUTHOR + +Gianni Ceccarelli <dakkar@thenautilus.net> + +=cut |