File Coverage

blib/lib/WWW/Webrobot/XML2Tree.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package WWW::Webrobot::XML2Tree;
2 31     31   98881 use strict;
  31         91  
  31         1217  
3 31     31   156 use warnings;
  31         61  
  31         1050  
4              
5             # Author: Stefan Trcek
6             # Copyright(c) 2004-2006 ABAS Software AG
7              
8             =head1 NAME
9              
10             WWW::Webrobot::XML2Tree - wrapper for L
11              
12             =cut
13              
14 31     31   71467 use XML::Parser;
  0            
  0            
15              
16              
17             sub new {
18             my $class = shift;
19             my $self = bless({}, ref($class) || $class);
20             $self->{parser} = new XML::Parser(Style => 'Tree', ErrorContext => 5);
21             #$self->{u2i} = Unicode::Lite::convertor('utf8', 'latin1') if $has_converter;
22             return $self;
23             }
24              
25             sub parsefile {
26             my ($self, $file) = @_;
27             my $tree = $self->{parser}->parsefile($file);
28             return $self->_parse0($tree);
29             }
30              
31             sub parse {
32             my ($self, $string) = @_;
33             my $tree = $self->{parser}->parse($string);
34             return $self->_parse0($tree);
35             }
36              
37             sub _parse0 {
38             my ($self, $tree) = @_;
39             unshift @$tree, {};
40             _delete_white_space($tree);
41             #use Data::Dumper; print "DUMP: ", Dumper($tree);
42             return $tree;
43             }
44              
45              
46             sub _delete_white_space {
47             my ($tree) = @_;
48             return _delete_white_space($tree->[1]) if scalar @$tree == 2; # root is special
49              
50             # Note: scalar @$tree % 2 == 1
51             for (my $i = scalar @$tree; $i > 1; $i-=2) {
52             if (! $tree->[$i-2] && $tree->[$i-1] =~ m/^\s*$/s) {
53             # ??? optimize: splice in the middle of an array may be inefficient
54             splice(@$tree, $i-2, 2);
55             }
56             elsif (ref $tree->[$i-1]) {
57             _delete_white_space($tree->[$i-1]);
58             }
59             }
60             }
61              
62              
63             {
64             my $s;
65              
66             sub _print_xml0 {
67             my ($tree, $prefix) = @_;
68             return "" if !$tree;
69             my $p = " " x $prefix;
70             for (my $i = 0; $i < scalar @$tree; $i += 2) {
71             my $tag = $tree->[$i];
72             my $content = $tree->[$i+1];
73             if (ref $content) {
74             my $attributes = $content->[0];
75             my $attr = "";
76             foreach (sort keys %$attributes) {
77             my $v = $attributes->{$_};
78             $v =~ s/'/\\'/g;
79             $attr .= " $_='$v'";
80             }
81             my @c = @$content[1 .. scalar @$content-1];
82             if (scalar @c) {
83             $s .= "$p<$tag$attr>\n";
84             _print_xml0(\@c, $prefix+1);
85             $s .= "$p\n";
86             }
87             else {
88             $s .= "$p<$tag$attr/>\n";
89             }
90             }
91             elsif (defined $content) { # $tag == 0
92             $content =~ s/^\s+//;
93             $content =~ s/\s+$//;
94             $s .= "$content\n";
95             }
96             }
97             return $s;
98             }
99              
100             sub print_xml {
101             $s = "";
102             my ($tree) = @_;
103             _print_xml0($tree, 0);
104             return $s;
105             }
106              
107             }
108              
109              
110             1;