File Coverage

blib/lib/XML/XPathScript.pm
Criterion Covered Total %
statement 321 376 85.3
branch 91 176 51.7
condition 17 31 54.8
subroutine 57 57 100.0
pod 18 21 85.7
total 504 661 76.2


line stmt bran cond sub pod time code
1             package XML::XPathScript;
2             our $AUTHORITY = 'cpan:YANICK';
3             # ABSTRACT: a Perl framework for XML stylesheets
4             $XML::XPathScript::VERSION = '2.00';
5 26     26   1888902 use strict;
  26         133  
  26         682  
6 26     26   112 use warnings;
  26         46  
  26         570  
7 26     26   105 use Carp;
  26         38  
  26         5842  
8              
9              
10             sub current {
11 177 50   177 1 347 croak 'Wrong context for calling current()'
12             unless defined $XML::XPathScript::current;
13              
14 177         375 return $XML::XPathScript::current;
15             }
16              
17              
18             sub interpolation {
19 66     66 1 130 my $self = shift;
20 66         159 return $self->interpolating( @_ );
21             }
22              
23             sub interpolating {
24 66     66 0 84 my $self=shift;
25              
26 66 50       192 if ( @_ ) {
27             $self->processor->set_interpolation(
28             $self->{interpolating} = shift
29 66         150 );
30             }
31              
32 66   100     187 return $self->{interpolating} || 0;
33             }
34              
35              
36             sub interpolation_regex {
37 64     64 1 97 my $self = shift;
38              
39 64 50       133 if ( my $regex = shift ) {
40             $self->processor->set_interpolation_regex(
41 64         113 $self->{interpolation_regex} = $regex
42             )
43             }
44              
45 64         128 return $self->{interpolation_regex};
46             }
47              
48              
49              
50             sub binmode {
51 2     2 1 8 my ($self)=@_;
52 2         6 $self->{binmode}=1;
53 2         38 $self->{processor}->enable_binmode;
54 2 50       14 binmode ORIGINAL_STDOUT if (! defined $self->{printer});
55 2         6 return;
56             }
57              
58              
59 26     26   165 use vars qw( $XML_parser $debug_level );
  26         42  
  26         1188  
60              
61 26     26   9073 use Symbol;
  26         15300  
  26         1364  
62 26     26   167 use File::Basename;
  26         49  
  26         2042  
63 26     26   10724 use XML::XPathScript::Processor;
  26         69  
  26         2906  
64 26     26   155 use XML::XPathScript::Template;
  26         41  
  26         29635  
65              
66             our $XML_parser = 'XML::LibXML';
67              
68             my %use_parser = (
69             'XML::LibXML' => 'use XML::LibXML',
70             'XML::XPath' => <<'END_USE',
71             use XML::XPath 1.0;
72             use XML::XPath::XMLParser;
73             use XML::XPath::Node;
74             use XML::XPath::NodeSet;
75             use XML::Parser;
76             END_USE
77             );
78              
79             die "parser $XML_parser unknown\n" unless $use_parser{$XML_parser};
80 25     25   13286 eval $use_parser{$XML_parser}.";1"
  25         783480  
  25         155  
81             or die "couldn't import $XML_parser";
82              
83             # internal variable for debugging information.
84             # 0 is total silence and 10 is complete verbiage
85             $debug_level = 0;
86              
87             sub import
88             {
89 30     30   1883 my $self = shift @_;
90              
91 30 50       173 if ( grep { $_ eq 'XML::XPath' } @_ ) {
  1 50       2  
92 1         29 $XML::XPathScript::XML_parser = 'XML::XPath';
93             }
94 1         5 elsif ( grep { $_ eq 'XML::LibXML' } @_ ) {
95 1         1 $XML::XPathScript::XML_parser = 'XML::LibXML';
96             }
97 30         24795 return;
98             }
99              
100              
101             sub new {
102 64     64 1 24083 my $class = shift;
103 64 50       244 die "Invalid hash call to new" if @_ % 2;
104 64         208 my %params = @_;
105 64         132 my $self = \%params;
106 64         115 bless $self, $class;
107 64         300 $self->{processor} = XML::XPathScript::Processor->new;
108 64 100       253 $self->set_xml( $params{xml} ) if $params{xml};
109              
110             $self->interpolation( exists $params{interpolation}
111 64 50       253 ? $params{interpolation} : 1 );
112              
113             $self->interpolation_regex( $params{interpolation_regex}
114 64   33     501 || qr/{(.*?)}/ );
115              
116              
117              
118 64 50       145 if ( $XML::XPathScript::XML_parser eq 'XML::XPath' ) {
119 1         2 require XML::XPath;
120 1         11 require XML::XPath::XMLParser;
121 1         6 require XML::XPath::Node;
122 1         2 require XML::XPath::NodeSet;
123 1         32 require XML::Parser;
124             }
125             else {
126 64         242 require XML::LibXML;
127             }
128              
129 64 50       139 croak $@ if $@;
130            
131 64         177 return $self;
132             }
133              
134              
135             sub transform {
136 22     22 1 2260 my( $self, $xml, $stylesheet, $args ) = @_;
137 22         36 my $output;
138            
139 22 100       62 $self->set_xml( $xml ) if $xml;
140              
141 22 100       50 if ( $stylesheet ) {
142 6         18 $self->{compiledstylesheet} = undef;
143 6         31 $self->{stylesheet} = $stylesheet;
144             }
145              
146 22 100       90 $self->process( \$output, $args ? @$args : () );
147              
148 21         83 return $output;
149             }
150              
151              
152             sub set_dom {
153 1     1 1 33 my( $self, $dom ) = @_;
154 1         5 $self->{dom} = $dom;
155 1         2 $self->{processor}->set_dom( $dom );
156 1         5 return $self;
157             }
158              
159              
160             sub set_xml {
161 77     77 1 374 my( $self, $xml ) = @_;
162              
163 77         129 $self->{xml} = $xml;
164              
165 77 100       262 my $retval = ref $xml ? $self->_set_xml_ref()
166             : $self->_set_xml_scalar()
167             ;
168              
169 77         317 $self->{processor}->set_dom( $self->{dom} );
170            
171 77         125 return $retval;
172              
173             # FIXME
174              
175 1         36 my $xpath;
176              
177              
178             # a third option should be auto, for which we
179             # would use the already-defined object
180 1 0       5 if( $XML_parser eq 'auto' )
181             {
182 1 0       2 if (UNIVERSAL::isa($self->{xml},"XML::XPath"))
    0          
183             {
184 1         5 $xpath=$self->{xml};
185 1         6 $XML_parser = 'XML::XPath';
186             }
187             elsif(UNIVERSAL::isa($self->{xml},"XML::LibXML" ))
188             {
189 1         2 $xpath=$self->{xml};
190 1         32 $XML_parser = 'XML::LibXML';
191             }
192             }
193              
194 1 0       6 if (UNIVERSAL::isa($self->{xml},"XML::XPath"))
    0          
195             {
196 1 0 0     1 if( $XML_parser eq 'XML::XPath' or $XML_parser eq 'auto' )
197             {
198 1         27 $xpath=$self->{xml};
199 1         4 $XML_parser = 'XML::XPath';
200             }
201             else # parser if XML::LibXML
202             {
203 1         2 $xpath = XML::LibXML->parse_string( $self->{xml}->toString )->documentElement;
204             }
205             }
206             elsif (UNIVERSAL::isa($self->{xml},"XML::libXML"))
207             {
208 1 0 0     5 if( $XML_parser eq 'XML::LibXML' or $XML_parser eq 'auto' )
209             {
210 1         5 $xpath=$self->{xml};
211 1         2 $XML_parser = 'XML::LibXML';
212             }
213             else # parser if xpath
214             {
215 1         21 $xpath = new XML::XPath( xml => $self->{xml}->toString );
216             }
217             }
218             else
219             {
220 1 0       4 $XML_parser = 'XML::LibXML' if $XML_parser eq 'auto';
221              
222 1 0       1 if (ref($self->{xml}))
223             {
224             $xpath= ( $XML_parser eq 'XML::LibXML' ) ?
225             XML::LibXML->new->parse_fh( $self->{xml} )->documentElement :
226             XML::XPath->new(ioref => $self->{xml})
227 1 0       44 }
228             }
229              
230 1         5 $self->{dom} = $xpath;
231             }
232              
233             sub _set_xml_ref {
234 8     8   26 my $self = shift;
235 8         18 my $xml = $self->{xml};
236              
237 8 50       26 if ( $XML_parser eq 'XML::LibXML' ) {
238 8 100       46 if ( $xml->isa( 'XML::LibXML::Document' ) ) {
239 2         24 $self->{dom} = $xml;
240 2         6 return;
241             }
242              
243 7 100       29 if ( $xml->isa( 'XML::LibXML::Node' ) ) {
244 2         39 my $dom = XML::LibXML::Document->new;
245 2         9 $dom->setDocumentElement( $xml );
246 2         17 $self->{dom} = $dom;
247 2         7 return;
248             }
249             }
250             else { # XML::XPath
251 0 0       0 if ( $xml->isa( 'XML::XPath' ) ) {
252 0         0 $self->{dom} = $xml;
253 0         0 return;
254             }
255              
256 0 0       0 if( $xml->isa( 'XML::XPath::Node' ) ) {
257             # evil hack
258 0         0 my $dom = XML::XPath->new( xml => $xml->toString );
259 0         0 $self->{dom} = $dom;
260 0         0 return;
261             }
262             }
263              
264             # try to read it as an io
265 5 50       31 $self->{dom} = $XML_parser eq 'XML::LibXML'
266             ? XML::LibXML->new->parse_fh( $xml )->documentElement
267             : XML::XPath->new(ioref => $xml)
268             ;
269              
270 5         3454 return;
271             }
272              
273             sub _set_xml_scalar {
274 69     70   98 my $self = shift;
275 69         116 my $xml = $self->{xml};
276              
277             # is it a file?
278 69 50 100     404 if( index( $xml, "\n" ) == -1 and # quick'n'dirty checks
      66        
      66        
279             index( $xml, '<' ) == -1 and # for non-filename characters
280             index( $xml, '>' ) == -1 and -f $xml ) {
281 1 50       33 open my $fh, '<', $xml or croak "couldn't open xml file $xml: $!";
282              
283 1 50       9 $self->{dom} = $XML_parser eq 'XML::LibXML'
284             ? XML::LibXML->new->parse_file( $xml )->documentElement
285             : XML::XPath->new( filename => $xml )
286             ;
287              
288 1         251 return;
289             }
290              
291             # then it must be a string
292              
293 68 50       339 $self->{dom} = $XML_parser eq 'XML::LibXML'
294             ? XML::LibXML->new->parse_string( $xml )->documentElement
295             : XML::XPath->new( xml => $xml );
296              
297 68         12713 return;
298             }
299              
300              
301             sub set_stylesheet {
302 9     10 1 36 my ( $self, $stylesheet ) = @_;
303              
304 9         31 $self->{compiledstylesheet} = undef;
305 9         17 $self->{stylesheet} = $stylesheet;
306              
307 9 50       34 $self->compile if $self->{stylesheet};
308             }
309              
310              
311             sub process {
312 73     74 1 582 my ($self, $printer, @extravars) = @_;
313              
314 73 100       214 do { $$printer="" } if (UNIVERSAL::isa($printer, "SCALAR"));
  66         115  
315 73 100       170 $self->{printer}=$printer if $printer;
316              
317 73 50       1109 croak "xml document not defined" unless $self->{dom};
318              
319             # FIXME
320 73 50       442 eval { $self->{dom}->ownerDocument->setEncoding( "UTF-8" ) }
  73         526  
321             if $XML_parser eq 'XML::LibXML';
322              
323             {
324 73         179 local *ORIGINAL_STDOUT;
  73         167  
325 73         296 *ORIGINAL_STDOUT = *STDOUT;
326 73         129 local *STDOUT;
327              
328             # Perl 5.6.1 dislikes closed but tied descriptors (causes SEGVage)
329 73 50       640 *STDOUT = *ORIGINAL_STDOUT if $^V lt v5.7.0;
330              
331 73         456 tie *STDOUT, __PACKAGE__;
332 73 100       263 $self->compile unless $self->{compiledstylesheet};
333 73         1711 my $retval = $self->{compiledstylesheet}->( $self, @extravars );
334 71         311 untie *STDOUT;
335 71         241 return $retval;
336             }
337             }
338              
339              
340             sub extract {
341 94     95 1 195 my ($self,$stylesheet,@includestack) = @_;
342              
343 94   50     360 my $filename = $self->{stylesheet_dependencies}[0] || "stylesheet";
344              
345 94         200 my $contents = $self->read_stylesheet( $stylesheet );
346              
347 94         14905 my @tokens = split /(<%[-=~#@]*|-?%>)/, $contents;
348              
349 26     26   192 no warnings qw/ uninitialized /;
  26         51  
  26         19904  
350              
351 94         146 my $script;
352 94         154 my $line = 1;
353             TOKEN:
354 94         219 while ( @tokens ) {
355 337         470 my $token = shift @tokens;
356              
357 337 100       683 if ( -1 == index $token, '<%' ) {
358 206         337 $line += $token =~ tr/\n//;
359 206 100 100     672 $token =~ s/\s+$// if -1 < index $tokens[0], '<%'
360             and -1 < index $tokens[0], '-';
361 206         309 $token =~ s/\|/\\\|/g;
362             # check for include
363 206         325 $token =~ s{}
  19         54  
364             { '|);'
365             . $self->include_file( $2, @includestack)
366 206 100       422 . 'print(q|'}seg;
367             $script .= 'print(q|'.$token.'|);' if length $token;
368 206         471  
369             next TOKEN;
370             }
371 131         334  
372             $script .= "\n#line $line $filename\n";
373 131         190  
374 131         169 my $opening_tag = $token;
375             my $code;
376 131         160 my $closing_tag;
377 131         247 my $level = 1;
378 326         460 while( @tokens ) {
379 326 100       572 my $t = shift @tokens;
380 326 100       520 $level++ if -1 < index $t, '<%';
381 326 100       492 $level-- if -1 < index $t, '%>';
382 131         169 if ( $level == 0 ) {
383 131         175 $closing_tag = $t;
384             last;
385 195         444 }
386             $code .= $t;
387             }
388 131 50       212  
389             die "stylesheet <% %>s are unbalanced: $opening_tag$code\n"
390             unless $closing_tag;
391 131         299  
392             $line += $code =~ tr/\n//;
393 131 100       398  
    100          
    100          
    100          
394 53         123 if ( -1 < index $opening_tag, '=' ) {
395             $script .= 'print( '.$code.' );';
396             }
397 15         48 elsif ( -1 < index $opening_tag, '~' ) {
398 15         51 $code =~ s/^\s+//;
399 15         33 $code =~ s/\s+$//;
400             $script .= 'print $processor->apply_templates( qq<'. $code .'> );';
401             }
402             elsif( -1 < index $opening_tag, '#' ) {
403             # do nothing
404             }
405 3         16 elsif( -1 < index $opening_tag, '@' ) {
406 3 50       12 $code =~ s/^\s+(\S+).*?\n//; # strip first line
407             my $tag = $1
408             or die "tag name missing in <%\@ %> at line $line\n";
409 3         5  
410 3         37 my $here_delimiter = 'END_TAG';
411 0         0 while ( $code =~ /$here_delimiter/ ) {
412             $here_delimiter .= 'x';
413 3         12 }
414             $script .= <
415             \$template->set( $tag => { content => <<'$here_delimiter' } );
416             $code
417             $here_delimiter
418             END_SNIPPET
419             }
420             else {
421 56         347 # always add a ';', just in case
422             $script .= $code . ';';
423             }
424 131 100       322  
425 18         54 if ( -1 < index $closing_tag, '-' ) {
426 18         33 $tokens[0] =~ s/^\s*//;
427 18         37 my $temp = $&;
428             $line += $temp =~ tr/\n//;
429             }
430             }
431 94         383  
432             return $script;
433              
434             # FIXME not needed anymore
435 0         0 # <%- -%> magic
436 0         0 $contents =~ s#(\s+)<%-([=~]?)#<%$2$1#gs;
437             $contents =~ s#-%>(\s+)#$1%>#gs;
438              
439 0         0 # <%~ %> magic
440             $contents =~ s#<%~\s+(\S+)\s+%>#<%= apply_templates( qq<$1> ) %>#gs;
441 0         0  
442             $script="#line 1 $filename\n",
443             $line = 1;
444 0         0  
445 0         0 while ($contents =~ /\G(.*?)()/gcs) {
460 0 0       0 last if $1 eq '-->';
461             $params{$2} = $4 if (defined $2);
462             }
463              
464 0 0       0 die "No matching file attribute in #include at line $line"
465             unless $params{file};
466 25     25   169  
  25         64  
  25         16028  
467 0         0 no warnings qw/ uninitialized /;
468             $script .= $self->include_file($params{file},@includestack);
469             }
470 0 0       0 else {
471 0         0 $contents =~ /\G(.*?)%>/gcs || die "No terminating '%>' after line $line";
472 0 0       0 my $perl = $1;
473 0         0 if( $type ne '<%#' ) {
474 0         0 $perl =~ s/;?$/;/s; # add on ; if its missing. As in <% $foo = 'Hello' %>
475             $script .= $perl;
476 0         0 }
477             $line += $perl =~ tr/\n//;
478             }
479             }
480 0 0       0  
481 0         0 if ($contents =~ /\G(.+)/gcs) {
482 0         0 my $text = $1;
483 0         0 $text =~ s/\|/\\\|/g;
484             $script .= "print(q|$text|);";
485             }
486 0         0  
487             return $script;
488             }
489              
490              
491             sub read_stylesheet
492 111     112 1 187 {
493             my( $self, $stylesheet ) = @_;
494            
495             # $stylesheet can be a filehandler
496 111 100       210 # or a string
497 20         74 if( ref($stylesheet) ) {
498 20         758 local $/;
499             return <$stylesheet>;
500             }
501 91         192 else {
502             return $stylesheet;
503             }
504            
505             }
506              
507              
508 19     20 1 61 sub include_file {
509             my ($self, $filename, @includestack) = @_;
510 19 50       59  
511             if ( $filename !~ m#^\.?/# ) {
512             # We guarantee that all values we insert into @includestack begin
513             # either with "/" or "./". This allows us to do the relative
514             # directory thing, and at the same time we get to safely ignore
515             # bizarre URIs inserted by inheriting classes.
516 19 100 66     254  
517             my $reldir = $includestack[0] && $includestack[0] =~ m#^\.?/#
518             ? dirname($includestack[0])
519             : '.'
520             ;
521 19         48  
522             $filename = "$reldir/$filename";
523             }
524            
525 19 100       45 # are we going recursive?
  6         15  
526 2         13 if ( grep { $_ eq $filename } @includestack ) {
527             warn 'loop detected in stylesheet include chain: ',
528 2         9 join( ' => ', reverse(@includestack), $filename ), "\n";
529             return undef;
530             }
531 17         23  
532 17 50       40 my $stylesheet;
533 17 50       543 unless ( $stylesheet = $self->{stylesheet_cache}{$filename} ) {
534             open my $fh, '<', $filename
535 17         68 or Carp::croak "Can't read include file '$filename': $!";
536             $stylesheet = $self->{stylesheet_cache}{$filename}
537             = $self->read_stylesheet( $fh );
538             }
539 17         109  
540             return $self->extract($stylesheet, $filename, @includestack);
541             }
542              
543              
544              
545             # Internal documentation: the return value is an anonymous sub whose
546             # prototype is
547             # &$compiledfunc($xpathscriptobj, $val1, $val2,...);
548              
549 69     70 1 134 sub compile {
550             my ($self,@extravars) = @_;
551 69         166  
552             $self->{compiledstylesheet} = undef;
553 69         81  
554 69         136 my $stylesheet;
555             $self->{stylesheet_cache} = {};
556 69 100       170  
    50          
557 59         104 if (exists $self->{stylesheet}) {
558             $stylesheet=$self->{stylesheet};
559             }
560             elsif (exists $self->{stylesheetfile}) {
561             # This hack fails if $self->{stylesheetfile} contains
562             # double quotes. I think we can ignore this and get
563 10         25 # away.
564             $stylesheet=qq::;
565             }
566 0         0 else {
567             die "Cannot compile without a stylesheet\n";
568             };
569 69         143  
570             my $script = $self->extract($stylesheet);
571 69         160  
572             my $package=gen_package_name();
573 69         148  
574             my $extravars = join ',', @extravars;
575 69         132  
576             my $processor = $self->{processor};
577              
578             # needs to be eval'ed first for the constants
579 69         4131 # to be seen
580             eval "package $package;"
581             ."\$processor->import_functional();";
582 69         735
583             my $eval = <
584             package $package;
585             no strict; # Don't moan on sloppyly
586             no warnings; # written stylesheets
587            
588             use $XML_parser;
589              
590             sub {
591             my (\$self, $extravars ) = \@_;
592             my \$processor = processor();
593             local \$XML::XPathScript::current=\$self;
594             my \$t = \$processor->{template}
595             = XML::XPathScript::Template->new();
596             my \$template = \$t;
597             local \$XML::XPathScript::trans = \$t;
598             #\$processor->{doc} = \$self->{dom};
599             #\$processor->{parser} = '$XML_parser';
600             #\$processor->{binmode} = \$self->{binmode};
601             #\$processor->{is_interpolating} = \$self->interpolation;
602             #\$processor->{interpolation_regex} = \$self->interpolation_regex;
603              
604             $script
605             }
606             EOT
607              
608 69         258 #warn "script ready for compil: $eval";
609 69         425 local $^W;
610 22     22   136 $self->debug( 10, "Compiling code:\n $eval" );
  22     22   55  
  22     22   615  
  22     13   119  
  22     13   40  
  22     13   885  
  22     7   124  
  22     7   39  
  22     7   156  
  13     5   77  
  13     5   51  
  13     5   332  
  13     5   60  
  13     5   21  
  13     5   397  
  13     1   63  
  13     1   25  
  13     1   89  
  7         40  
  7         14  
  7         208  
  7         35  
  7         18  
  7         227  
  7         32  
  7         10  
  7         40  
  5         31  
  5         7  
  5         128  
  5         24  
  5         8  
  5         164  
  5         25  
  5         15  
  5         28  
  5         30  
  5         11  
  5         115  
  5         23  
  5         8  
  5         166  
  5         24  
  5         8  
  5         29  
  69         4501  
611 69 50       35133 my $retval = eval $eval;
612             die $@ unless defined $retval;
613 69         290  
614             return $self->{compiledstylesheet} = $retval;
615             }
616              
617              
618              
619 25     25   174 sub print {
  25         55  
  25         15639  
620 166     167 1 329 no warnings qw/ uninitialized /;
621 166         233 my ($self, @text)=@_;
622             my $printer=$self->{printer};
623 166 100       590  
    100          
    100          
624 1         5 if (!defined $printer) {
625             print ORIGINAL_STDOUT @text;
626 10         29 } elsif (ref($printer) eq 'CODE') {
627             $printer->(@text);
628 151         367 } elsif (UNIVERSAL::isa($printer, 'SCALAR')) {
629             $$printer.= join '', @text;
630 4         9 } else {
631 4         12 local $\=undef;
632             print $printer @text;
633             };
634 166         621  
635             return;
636             }
637              
638              
639             # $self->debug( $level, $message )
640             # Display debugging information
641              
642 71 50   72 0 202 sub debug {
643             warn $_[2] if $_[1] <= $debug_level;
644             }
645              
646              
647 1     2 1 6 sub get_stylesheet_dependencies {
648 1 50       5 my $self = shift;
649 1         2 $self->compile unless $self->{compiledstylesheet};
  1         12  
650             return sort keys %{$self->{stylesheet_cache}};
651             }
652              
653              
654 131     132 1 447 sub processor {
655             return $_[0]->{processor};
656             }
657              
658              
659             do {
660             my $uniquifier;
661 69     70 0 104 sub gen_package_name {
662 69         173 $uniquifier++;
663             return "XML::XPathScript::STYLESHEET$uniquifier";
664             }
665             };
666              
667              
668             sub document {
669 1     2 1 2 # warn "Document function called\n";
670             my( $self, $uri ) = @_;
671 1         2
672 1 50       4 my( $results, $parser );
    50          
673 0 0       0 if( $XML_parser eq 'XML::XPath' ) {
674             my $xml_parser = XML::Parser->new(
675             ErrorContext => 2,
676             Namespaces => $XML::XPath::VERSION < 1.07 ? 1 : 0,
677             # ParseParamEnt => 1,
678             );
679 0         0
680 0         0 $parser = XML::XPath::XMLParser->new(parser => $xml_parser);
681             $results = XML::XPath::NodeSet->new();
682             }
683 1         4 elsif ( $XML_parser eq 'XML::LibXML' ) {
684 1         16 $parser = XML::LibXML->new;
685             $results = XML::LibXML::Document->new;
686             }
687 0         0 else {
688             $self->die( "xml parser not valid: $XML_parser" );
689             }
690              
691 1         2
692             my $newdoc;
693 1 50 33     13 # TODO: must handle axkit: scheme a little more cleverly
694 0         0 if ($uri =~ /^\w\w+:/ and $uri !~ /^axkit:/ ) { # assume it's scheme://foo uri
695 0         0 eval {
696 0         0 $self->debug( 5, "trying to parse $uri" );
697 0         0 eval "use LWP::Simple";
698 0         0 $newdoc = $parser->parse_string( LWP::Simple::get( $uri ) );
699             $self->debug( 5, "Parsed OK into $newdoc\n" );
700 0 0       0 };
701 0         0 if (my $E = $@) {
702             $self->debug("Parse of '$uri' failed: $E" );
703             }
704             }
705 1         6 else {
706 1 50       4 $self->debug(3, "Parsing local: $uri\n");
    0          
707 1         4 if( $XML_parser eq 'XML::LibXML' ) {
708             $newdoc = $parser->parse_file( $uri );
709 0         0 } elsif( $XML_parser eq 'XML::XPath' ) {
710             $newdoc = XML::XPath->new( filename => $uri );
711 0         0 }
712             else { die "invalid parser: $XML_parser\n"; }
713             }
714 1 50       256  
715 1 50       8 if( $newdoc ) {
    0          
716 1         8 if( $XML_parser eq 'XML::LibXML' ) {
717             $results = $newdoc->documentElement();
718             }
719 0         0 elsif( $XML_parser eq 'XML::XPath' ) {
720             $results = $newdoc->findnodes('/')->[0]->getChildNodes->[0];
721             }
722             }
723 1         3
724 1         4 $self->debug(8, "XPathScript: document() returning");
725             return $results;
726             }
727 73     74   135  
  73         186  
728             sub TIEHANDLE { my $self = ''; bless \$self, $_[0] }
729 166     167   1192 sub PRINT {
730 166         279 my $self = shift;
731             return XML::XPathScript::current()->print( @_ );
732             }
733 1     2   15 sub BINMODE {
734             return XML::XPathScript::current()->binmode( @_ );
735             }
736              
737             1;
738              
739             __END__