File Coverage

blib/lib/XML/XPathScript.pm
Criterion Covered Total %
statement 48 331 14.5
branch 4 176 2.2
condition 4 31 12.9
subroutine 15 39 38.4
pod n/a
total 71 577 12.3


line stmt bran cond sub pod time code
1             package XML::XPathScript;
2              
3 22     22   355790 use strict;
  22         54  
  22         944  
4 22     22   117 use warnings;
  22         37  
  22         682  
5 22     22   110 use Carp;
  22         37  
  22         8622  
6              
7             # $Revision$ - $Date$
8              
9             =pod
10              
11             =head1 NAME
12              
13             XML::XPathScript - a Perl framework for XML stylesheets
14              
15             =head1 SYNOPSIS
16              
17             use XML::XPathScript;
18              
19             # the short way
20             my $xps = XML::XPathScript->new;
21             my $transformed = $xps->transform( $xml, $stylesheet );
22              
23             # having the output piped to STDOUT directly
24             my $xps = XML::XPathScript->new( xml => $xml, stylesheet => $stylesheet );
25             $xps->process;
26              
27             # caching the compiled stylesheet for reuse and
28             # outputting to multiple files
29             my $xps = XML::XPathScript->new( stylesheetfile => $filename )
30             foreach my $xml (@xmlfiles) {
31             my $transformed = $xps->transform( $xml );
32              
33             # do stuff with $transformed ...
34             };
35              
36             # Making extra variables available to the stylesheet dialect:
37             my $xps = XML::XPathScript->new;
38             $xps->compile( qw/ $foo $bar / );
39              
40             # in stylesheet, $foo will be set to 'a'
41             # and $bar to 'b'
42             $xps->transform( $xml, $stylesheet, [ 'a', 'b' ] );
43              
44             =head1 DESCRIPTION
45              
46             XPathScript is a stylesheet language similar in many ways to XSLT (in
47             concept, not in appearance), for transforming XML from one format to
48             another (possibly HTML, but XPathScript also shines for non-XML-like
49             output).
50              
51             Like XSLT, XPathScript offers a dialect to mix verbatim portions of
52             documents and code. Also like XSLT, it leverages the powerful
53             ``templates/apply-templates'' and ``cascading stylesheets'' design
54             patterns, that greatly simplify the design of stylesheets for
55             programmers. The availability of the I query language inside
56             stylesheets promotes the use of a purely document-dependent,
57             side-effect-free coding style. But unlike XSLT which uses its own
58             dedicated control language with an XML-compliant syntax, XPathScript
59             uses Perl which is terse and highly extendable.
60              
61             The result of the merge is an extremely powerful tool for rendering
62             complex XML documents into other formats. Stylesheets written in
63             XPathScript are very easy to create, extend and reuse, even if they
64             manage hundreds of different XML tags.
65              
66             =head1 STYLESHEET WRITER DOCUMENTATION
67              
68             If you are interested to write stylesheets, refers to the
69             B manpage. You might also want
70             to take a peek at the manpage of B, a program
71             bundled with this module to perform XPathScript transformations
72             via the command line.
73              
74             =head1 STYLESHEET UTILITY METHODS
75              
76             Those methods are meants to be used from within a stylesheet.
77              
78             =head2 current
79              
80             $xps = XML::XPathScript->current
81              
82             This class method returns
83             the stylesheet object currently being applied. This can be called from
84             anywhere within the stylesheet, except a BEGIN or END block or
85             similar. B that using the return value for altering (as
86             opposed to reading) stuff from anywhere except the stylesheet's top
87             level is unwise.
88              
89             =cut
90              
91             sub current {
92 0 0   0   0 croak 'Wrong context for calling current()'
93             unless defined $XML::XPathScript::current;
94              
95 0         0 return $XML::XPathScript::current;
96             }
97              
98             =head2 interpolation
99              
100             $interpolate = $XML::XPathScript::current->interpolation
101             $interpolate = $XML::XPathScript::current->interpolation( $boolean )
102              
103             Gets (first call form) or sets (second form) the XPath interpolation
104             boolean flag. If true, values set in C< pre > and C< post >
105             may contain expressions within curly braces, that will be
106             interpreted as XPath expressions and substituted in place.
107              
108             For example, when interpolation is on, the following code
109              
110             $template->set( link => { pre => '',
111             post => '' } );
112              
113             is enough for rendering a C<< >> element as an HTML hyperlink.
114             The interpolation-less version is slightly more complex as it requires a
115             C:
116              
117             sub link_testcode {
118             my ($node, $t) = @_;
119             my $url = $node->findvalue('@url');
120             $t->set({ pre => "",
121             post => "" });
122             return DO_SELF_AND_KIDS();
123             };
124              
125             Interpolation is on by default.
126              
127             =cut
128              
129             sub interpolation {
130 0     0   0 my $self = shift;
131 0         0 return $self->interpolating( @_ );
132             }
133              
134             sub interpolating {
135 0     0   0 my $self=shift;
136              
137 0 0       0 if ( @_ ) {
138 0         0 $self->processor->set_interpolation(
139             $self->{interpolating} = shift
140             );
141             }
142              
143 0   0     0 return $self->{interpolating} || 0;
144             }
145              
146             =head2 interpolation_regex
147              
148             $regex = $XML::XPathScript::current->interpolation_regex
149             $XML::XPathScript::current->interpolation_regex( $regex )
150              
151             Gets or sets the regex to use for interpolation. The value to be
152             interpolated must be capture by $1.
153              
154             By default, the interpolation regex is qr/{(.*?)}/.
155              
156             Example:
157              
158             $XML::XPathScript::current->interpolation_regex( qr#\|(.*?)\|# );
159              
160             $template->set( bird => { pre => '|@name| |@gender| |@type|' } );
161              
162             =cut
163              
164             sub interpolation_regex {
165 0     0   0 my $self = shift;
166              
167 0 0       0 if ( my $regex = shift ) {
168 0         0 $self->processor->set_interpolation_regex(
169             $self->{interpolation_regex} = $regex
170             )
171             }
172              
173 0         0 return $self->{interpolation_regex};
174             }
175              
176              
177             =head2 binmode
178              
179             Declares that the stylesheet output is B in UTF-8, but instead in
180             an (unspecified) character encoding embedded in the stylesheet source
181             that neither Perl nor XPathScript should have any business dealing
182             with. Calling C<< XML::XPathScript->current()->binmode() >> is an
183             B operation with the consequences outlined in L
184             Unicode mess>.
185              
186             =cut "
187              
188             sub binmode {
189 0     0   0 my ($self)=@_;
190 0         0 $self->{binmode}=1;
191 0         0 $self->{processor}->enable_binmode;
192 0 0       0 binmode ORIGINAL_STDOUT if (! defined $self->{printer});
193 0         0 return;
194             }
195              
196             =pod "
197              
198             =head1 TECHNICAL DOCUMENTATION
199              
200             The rest of this POD documentation is B useful to programmers who
201             just want to write stylesheets; it is of use only to people wanting to
202             call existing stylesheets or more generally embed the XPathScript
203             engine into some wider framework.
204              
205             I is an object-oriented class with the following features:
206              
207             =over
208              
209             =item *
210              
211             an I that allows the merging of the stylesheet
212             code with snippets of the output document. Don't be afraid, this is
213             exactly the same kind of stuff as in I, I
214             or other similar packages: instead of having text inside Perl (that
215             one Is), we have Perl inside text, with a special escaping
216             form that a preprocessor interprets and extracts. For XPathScript,
217             this preprocessor is embodied by the I shell tool (see
218             L) and also available through this package's
219             API;
220              
221             =item *
222              
223             a I, that does the apply-templates loop, starting
224             from the top XML node and applying templates to it and its subnodes as
225             directed by the stylesheet.
226              
227             =back
228              
229             When run, the stylesheet is expected to fill in the I