File Coverage

blib/lib/Data/Stag/XMLWriter.pm
Criterion Covered Total %
statement 71 86 82.5
branch 23 42 54.7
condition 2 5 40.0
subroutine 14 16 87.5
pod 3 12 25.0
total 113 161 70.1


line stmt bran cond sub pod time code
1             package Data::Stag::XMLWriter;
2              
3             =head1 NAME
4              
5             Data::Stag::XMLWriter - writes stag events into XML files
6              
7             =head1 SYNOPSIS
8              
9              
10             =cut
11              
12             =head1 DESCRIPTION
13              
14             =head1 PUBLIC METHODS -
15              
16             =cut
17              
18 14     14   85 use strict;
  14         53  
  14         595  
19 14     14   81 use base qw(Data::Stag::Writer);
  14         30  
  14         8256  
20 14     14   87 use Data::Stag::Util qw(rearrange);
  14         29  
  14         638  
21              
22 14     14   87 use vars qw($VERSION);
  14         29  
  14         14493  
23             $VERSION="0.14";
24              
25             sub unclosed {
26 663     663 0 746 my $self = shift;
27 663 50       1531 $self->{_unclosed} = shift if @_;
28 663         1212 return $self->{_unclosed};
29             }
30              
31             sub in_attr {
32 1768     1768 0 1968 my $self = shift;
33 1768 50       3385 $self->{_in_attr} = shift if @_;
34 1768         5214 return $self->{_in_attr};
35             }
36              
37              
38             sub ensure_closed {
39 1768     1768 0 1860 my $self = shift;
40 1768 100       4081 if ($self->{_unclosed}) {
41 663         1178 $self->o(">") ;
42 663         1187 $self->{_unclosed} = 0;
43             }
44 1768         2260 return;
45             }
46              
47             sub fmtstr {
48 0     0 0 0 return 'xml';
49             }
50              
51             sub indent_txt {
52 884     884 0 927 my $self = shift;
53 884         2116 my $stack = $self->stack;
54 884         3675 return " " x scalar(@$stack);
55             }
56              
57             sub this_line {
58 0     0 0 0 my $self = shift;
59 0 0       0 $self->{_this_line} = shift if @_;
60 0         0 return $self->{_this_line};
61             }
62              
63             sub o {
64 2708     2708 0 3191 my $self = shift;
65 2708         4759 my $o = "@_";
66 2708         12703 $self->addtext( $o );
67             }
68              
69             sub first_line {
70 28     28 0 44 my $self = shift;
71 28 50       88 $self->{_first_line} = shift if @_;
72 28         188 return $self->{_first_line};
73             }
74              
75              
76             sub start_event {
77 663     663 1 754 my $self = shift;
78 663         729 my $ev = shift;
79 663 50       1229 if (!defined($ev)) {
80 0         0 $ev = '';
81             }
82 663         1812 my $stack = $self->stack;
83 663 100       1378 if (!@$stack) {
84 28   50     97 $self->o($self->first_line || "");
85             }
86              
87 663 50       2252 if ($ev eq '@') {
    50          
    50          
    50          
88 0         0 $self->in_attr(1);
89             }
90             elsif ($ev eq '.') {
91             # pcdata for element with attributes
92             # do nothing
93             }
94             elsif ($self->in_attr) {
95 0         0 $self->o(" $ev=");
96             }
97             elsif ($ev eq '') {
98             # ignore null nodes
99             }
100             else {
101 663         1158 $self->ensure_closed;
102 663         1341 $self->o("\n". $self->indent_txt . "<$ev");
103 663         1514 $self->unclosed(1);
104             }
105 663         1848 push(@$stack, $ev);
106             }
107              
108             sub end_event {
109 663     663 1 815 my $self = shift;
110 663         795 my $ev = shift;
111 663         1476 my $stack = $self->stack;
112 663         1227 my $popped = pop(@$stack);
113 663 50       1277 return '' unless $popped;
114 663 50 33     20596 if ($ev && $popped ne $ev) {
115 0         0 warn("uh oh; $ev ne $popped");
116             }
117 663 50       1201 if (!$ev) {
118 0         0 $ev = $popped;
119             }
120 663 50       1166 if ($self->in_attr) {
    50          
121 0 0       0 if ($ev eq '@') {
122 0         0 $self->in_attr(0);
123 0         0 $self->ensure_closed;
124             }
125             }
126             elsif ($ev eq '.') {
127             # end of pcdata for element with attributes
128             }
129             else {
130 663         1116 $self->ensure_closed;
131 663 100       1265 if ($self->{_nl}) {
132 221         454 $self->o("\n" . $self->indent_txt)
133             }
134 663         1987 $self->o("");
135 663         1100 $self->{_nl} = 1;
136 663 100       1411 if (!@$stack) {
137 28         78 $self->o("\n");
138             }
139             }
140 663         2766 return $ev;
141             }
142             sub evbody {
143 442     442 1 504 my $self = shift;
144 442         557 my $body = shift;
145 442         1079 my $str= xmlesc($body);
146 442 50       910 if ($self->in_attr) {
147 0         0 $self->o("\"$str\"");
148             }
149             else {
150 442         771 $self->ensure_closed;
151 442         670 $self->{_nl} = 0;
152 442         844 $self->o($str);
153             }
154 442         1021 return;
155             }
156              
157             our $escapes = { '&' => '&',
158             '<' => '<',
159             '>' => '>',
160             '"' => '"'
161             };
162              
163             sub xmlesc {
164 442     442 0 510 my $w = shift;
165 442 50       1167 if (!defined $w) {
166 0         0 $w = '';
167             }
168 442         928 $w =~ s/([\&\<\>])/$escapes->{$1}/ge;
  0         0  
169 442         805 $w;
170             }
171              
172              
173              
174             1;