File Coverage

blib/lib/XML/Bits.pm
Criterion Covered Total %
statement 50 60 83.3
branch 8 14 57.1
condition n/a
subroutine 12 14 85.7
pod 5 5 100.0
total 75 93 80.6


line stmt bran cond sub pod time code
1             package XML::Bits;
2             $VERSION = v0.0.1;
3              
4 2     2   27114 use warnings;
  2         4  
  2         74  
5 2     2   11 use strict;
  2         4  
  2         63  
6 2     2   18 use Carp;
  2         5  
  2         210  
7              
8             use overload
9 1     1   4 '""' => sub {shift->stringify},
10 2     2   2073 fallback => 1;
  2         1247  
  2         17  
11              
12 2     2   131 use base 'Tree::Base';
  2         4  
  2         1647  
13 2     2   4585 use Class::Accessor::Classy;
  2         9439  
  2         17  
14             rw 'tag';
15             ro 'type';
16             lw 'atts';
17             ri 'doctype';
18             ro 'content';
19 2     2   422 no Class::Accessor::Classy;
  2         4  
  2         8  
20              
21             our @EXPORT_OK = qw(T);
22             BEGIN {
23 2     2   633 require Exporter;
24 2         1122 *import = \&Exporter::import;
25             }
26              
27             =head1 NAME
28              
29             XML::Bits - a tree of XML nodes
30              
31             =head1 SYNOPSIS
32              
33             use XML::Bits;
34              
35             my $div = XML::Bits->new(div =>);
36             $div->create_child(div =>)->create_child(div =>);
37              
38             print $div, "\n";
39              
40             =cut
41              
42             =head2 new
43              
44             my $node = XML::Bits->new($tag => [%attributes], @children);
45              
46             =cut
47              
48             sub new {
49 3     3 1 20 my $class = shift;
50 3         4 my $tag = shift;
51 3         20 my $self = $class->SUPER::new(tag => $tag);
52              
53 3 50       114 $self->{atts} = ref($_[0]) eq 'ARRAY' ? shift(@_) : [];
54 3         5 my @children = @_;
55              
56 3 100       73 if($self->tag eq '') {
57 1         6 $self->{type} = 'text';
58 1         4 $self->{content} = join('', @children);
59             }
60             else {
61 2         11 $self->{type} = 'node';
62             # TODO this is expensive unless we contextually disable re-rooting
63 2         4 foreach my $child (@children) {
64 1         4 $self->add_child($child);
65             }
66             }
67              
68 3         43 return($self);
69             } # new ################################################################
70              
71             =head2 add_child
72              
73             Adds a child, regardless of the child's previous parenthood.
74              
75             $node->add_child($child);
76              
77             NOTE: there's some questionable issues about the tree parentage and
78             rerooting here. Beware of bugs if you move elements around between
79             trees. ALSO NOTE: this API might change such that it is required to
80             use a different method for this sort of thing.
81              
82             =cut
83              
84             sub add_child {
85 2     2 1 5 my $self = shift;
86 2         3 my ($child) = @_;
87              
88 2         3 delete $child->{root};
89 2         3 delete $child->{parent};
90              
91 2         8 return $self->SUPER::add_child($child);
92             } # add_child ##########################################################
93              
94             =head2 is_text
95              
96             Returns true if this is a text node.
97              
98             $node->is_text;
99              
100             =cut
101              
102 0     0 1 0 sub is_text { shift->type eq 'text' }
103             ########################################################################
104              
105             =head2 stringify
106              
107             Stringification (and operator overloading support.)
108              
109             my $string = $node->stringify;
110              
111             =cut
112              
113             sub stringify {
114 3     3 1 3 my $self = shift;
115              
116 3 100       69 return($self->{content}) if($self->type eq 'text');
117              
118 2         61 my $string = '<' . $self->tag;
119 2 50       48 if(my $dt = $self->doctype) {
120 0         0 $string = '\n\n" . $string;
121             }
122              
123 2 50       55 if(my @atts = $self->atts) {
124 0         0 $string .= ' ' . join(' ',
125 0         0 map({$atts[2*$_] . '="' . $atts[2*$_+1] . '"'} 0..(($#atts-1)/2))
126             );
127             }
128              
129 2 50       21 if(my @kids = $self->children) {
130 2         27 $string .= '>' .
131 2         15 join('', map({$_->stringify} @kids)) .
132             'tag . '>';
133             }
134             else {
135 0         0 $string .= ' />';
136             }
137 2         77 return($string);
138             } # stringify ##########################################################
139              
140             =head2 T
141              
142             A shortcut tag constructor.
143              
144             T{tag => [%atts], @content};
145              
146             =cut
147              
148             sub T (&) {
149 0     0 1   my ($sub) = @_;
150 0           my @what = $sub->();
151             #warn "what: (@what)\n";
152 0           foreach my $item (@what) {
153 0 0         $item = __PACKAGE__->new('', $item) unless(ref($item));
154             }
155 0           return(__PACKAGE__->new(@what));
156             } # T ##################################################################
157              
158             =head1 AUTHOR
159              
160             Eric Wilhelm @
161              
162             http://scratchcomputing.com/
163              
164             =head1 BUGS
165              
166             If you found this module on CPAN, please report any bugs or feature
167             requests through the web interface at L. I will be
168             notified, and then you'll automatically be notified of progress on your
169             bug as I make changes.
170              
171             If you pulled this development version from my /svn/, please contact me
172             directly.
173              
174             =head1 COPYRIGHT
175              
176             Copyright (C) 2009 Eric L. Wilhelm, All Rights Reserved.
177              
178             =head1 NO WARRANTY
179              
180             Absolutely, positively NO WARRANTY, neither express or implied, is
181             offered with this software. You use this software at your own risk. In
182             case of loss, no person or entity owes you anything whatsoever. You
183             have been warned.
184              
185             =head1 LICENSE
186              
187             This program is free software; you can redistribute it and/or modify it
188             under the same terms as Perl itself.
189              
190             =cut
191              
192             # vi:ts=2:sw=2:et:sta
193             1;