File Coverage

blib/lib/XML/WriterX/Simple.pm
Criterion Covered Total %
statement 55 62 88.7
branch 40 54 74.0
condition 11 11 100.0
subroutine 7 7 100.0
pod 3 4 75.0
total 116 138 84.0


line stmt bran cond sub pod time code
1             package XML::WriterX::Simple;
2             $XML::WriterX::Simple::VERSION = '0.151400';
3             #ABSTRACT:Make XML production simpler.
4 2     2   30190 use 5.006;
  2         5  
  2         75  
5 2     2   7 use strict;
  2         3  
  2         61  
6 2     2   8 use warnings FATAL => 'all';
  2         6  
  2         1802  
7              
8              
9              
10             sub XML::Writer::produce{
11 21     21 0 5261 my $writer = shift;
12            
13             TAG:
14 21         45 while( my $tagName = shift ){
15 22         50 my ($attr, $children, $text) = XML::WriterX::Simple::arrange_args( $writer, shift );
16 22 100 100     112 if(($text//'') eq '' and !@$children){
      100        
17 1         4 $writer->emptyTag( $tagName, @$attr );
18             }
19             else{
20 21 100       28 if(ref($text) eq 'CODE'){
21 3         6 XML::WriterX::Simple::produce_content( $writer, $tagName => $text );
22             }
23             else{
24 18         38 $writer->startTag( $tagName, @$attr );
25 18 50       565 $writer->characters( $text ) if defined $text;
26 18         31 while( @$children ){
27 26         65 my ($tag, $content) = (shift(@$children), shift(@$children));
28 26 100 100     105 $tag = ".$tagName" if $tag =~ /^[&"]$/ and ref $content eq 'CODE';
29 26         36 XML::WriterX::Simple::produce_content( $writer, $tag => $content );
30             }
31 18         240 $writer->endTag( $tagName );
32             }
33             }
34             }
35             #return writer to allow chaining
36 21         441 $writer;
37             }
38              
39              
40             sub stringify{
41 16     16 1 18 local $_ = shift;
42 16 50       58 return $_ unless ref;
43 0 0       0 if(ref eq 'ARRAY'){
    0          
    0          
    0          
44             }
45             elsif(ref eq 'HASH'){
46             }
47             elsif(ref eq 'SCALAR'){
48 0         0 return $$_;
49             }
50             elsif(ref eq 'REF'){
51 0         0 return stringify( $$_ );
52             }
53 0         0 return "$_";#? REGEXP or GLOB or blessed object... : let's use perl stringifier
54             }
55              
56             sub arrange_args{
57 22     22 1 20 my ($writer, $tagContent) = @_;
58 22         13 my (@attr, @children, $text);
59 22 100       49 if(ref $tagContent eq 'CODE'){
    100          
60 3         3 $text = $tagContent;
61             }
62             elsif(defined $tagContent){
63 18 100       48 @_ = @$tagContent if ref $tagContent eq 'ARRAY';
64 18 100       30 @_ = %$tagContent if ref $tagContent eq 'HASH';
65 18 100       34 @_ = ('"', $$tagContent) if ref($tagContent) =~ /^(SCALAR|REF)$/;
66 18 100       35 @_ = ('"', $tagContent) if !ref $tagContent;
67 18         30 while( @_ ){
68 31         33 my ($tag,$content) = (shift, shift);
69 31 100 100     95 if($tag =~ /^#/){
    100          
    100          
70             #comment is added as a children
71 2         5 push @children, $tag => $content;
72             }
73             elsif($tag =~ /^:attr/ and ref($content) =~ /^(ARRAY|HASH)$/){
74             #multiple attributes in $content
75 1 50       6 my @attrs = $1 eq 'ARRAY' ? @$content : %$content;
76             #!warning if %attr != @$content : attribute name must be unique!
77 1         7 push @attr, shift(@attrs), shift(@attrs) while @attrs;
78             }
79             elsif($tag =~ /^:(.*)/){
80             #single attribute named $1 value is stringify($content)
81 4         13 push @attr, $1 => $content;
82             }
83             else{
84             #(processing instruction are added as a children like all other cases)
85 24         51 push @children, $tag => $content;
86             }
87             }
88             }
89 22         52 return (\@attr, \@children, $text);
90             }
91              
92              
93             #CANNOT:
94             # - produce a comment from a sub{}
95             # - produce a tag attributes from a sub{}
96             # - prodice attributes from a sub{} ?
97             sub produce_content{
98 29     29 1 31 my ($writer, $tag, $content) = @_;
99              
100 29 50       42 unless($tag){
101 0         0 warn "try to produce content without any tag name!";
102 0         0 $DB::single=1;
103 0         0 return;
104             }
105              
106 29 100       45 if(ref($content) eq 'CODE'){
107 5 100       19 $writer->startTag( $tag ) unless $tag =~ /^\./;
108 5         66 $content->( $writer, $tag );
109 5 100       49 $writer->endTag( $tag ) unless $tag =~ /^\./;
110 5         37 return;
111             }
112              
113 24 100       52 return $writer->characters( stringify( $content ) )
114             if $tag eq '"';
115              
116 10 100       34 return $writer->comment( stringify $content )
117             if $tag =~ /^#/;
118              
119 8 50       12 return $writer->pi( $1 => stringify $content )
120             if $tag =~ /^\?(.*)/;
121            
122 8 50       12 return $writer->produce( $tag, $$content )
123             if ref $content eq 'SCALAR';
124            
125 8         15 return $writer->produce( $tag, $content );
126             }
127              
128              
129             1; # End of XML::WriterX::Simple
130              
131             __END__