File Coverage

blib/lib/XML/Atom/Syndication/Writer.pm
Criterion Covered Total %
statement 50 60 83.3
branch 8 16 50.0
condition 2 9 22.2
subroutine 10 12 83.3
pod 5 7 71.4
total 75 104 72.1


line stmt bran cond sub pod time code
1             package XML::Atom::Syndication::Writer;
2 21     21   74 use strict;
  21         23  
  21         844  
3              
4 21     21   78 use base qw( Class::ErrorHandler );
  21         20  
  21         1551  
5              
6 21     21   10998 use XML::Writer;
  21         212394  
  21         630  
7 21     21   176 use XML::Elemental::Util qw( process_name );
  21         31  
  21         13645  
8              
9             my %NSPrefix = ( # default prefix table.
10             # '' => "http://www.w3.org/2005/Atom",
11             dc => "http://purl.org/dc/elements/1.1/",
12             dcterms => "http://purl.org/dc/terms/",
13             sy => "http://purl.org/rss/1.0/modules/syndication/",
14             trackback => "http://madskills.com/public/xml/rss/module/trackback/",
15             xhtml => "http://www.w3.org/1999/xhtml",
16             xml => "http://www.w3.org/XML/1998/namespace"
17             );
18              
19             sub new {
20 17     17 1 25 my $class = shift;
21 17         33 my $self = bless {}, $class;
22 17         53 $self->init(@_);
23             }
24              
25             sub init {
26 17     17 0 108 my %nsp = %NSPrefix; # clone
27 17         91 $_[0]->{__PREFIX} = \%nsp;
28 17         111 $_[0]->{__NS} = {reverse %nsp};
29 17         72 $_[0];
30             }
31              
32             sub set_prefix {
33 17     17 1 39 $_[0]->{__NS}->{$_[2]} = $_[1];
34 17         45 $_[0]->{__PREFIX}->{$_[1]} = $_[2];
35             }
36              
37 0     0 1 0 sub get_prefix { $_[0]->{__NS}->{$_[1]} }
38 0     0 1 0 sub get_namespace { $_[0]->{__PREFIX}->{$_[1]} }
39              
40             sub as_xml {
41 26     26 1 60 my ($self, $node, $is_full) = @_;
42 26         30 my $xml = '';
43 26         23 my $w;
44 26 50       49 if ($is_full) { # full doc
45 0         0 my ($name, $ns) = process_name($node->name);
46             $w = XML::Writer->new(
47             OUTPUT => \$xml,
48             NAMESPACES => 1,
49             PREFIX_MAP => $self->{__NS}, # FORCED_NS_DECLS => [ $ns ]
50 0         0 );
51 0         0 $w->xmlDecl('utf-8');
52             } else { # fragment
53 26         125 $w = XML::Writer->new(OUTPUT => \$xml, UNSAFE => 1);
54             }
55 26         3982 my $dumper;
56             $dumper = sub {
57 35     35   39 my $node = shift;
58 35 100       141 return encode_xml($w, $node->data)
59             if (ref $node eq 'XML::Elemental::Characters');
60 9         33 my ($name, $ns) =
61             process_name($node->name); # it must be an element then.
62 9 50       146 my $tag = $is_full ? [$ns, $name] : $name;
63 9         14 my @attr;
64 9         26 my $a = $node->attributes;
65 9         56 my $children = $node->contents;
66 9         53 foreach (keys %$a) {
67 0         0 my ($aname, $ans) = process_name($_);
68             next
69 0 0 0     0 if ( $ans eq 'http://www.w3.org/2000/xmlns/'
70             || $aname eq 'xmlns');
71 0 0 0     0 my $key = $is_full && $ans ? [$ans, $aname] : $aname;
72 0         0 push @attr, $key, $a->{$_};
73             }
74 9 50       33 if (@$children) {
75 9         47 $w->startTag($tag, @attr);
76 9         190 map { $dumper->($_) } @$children;
  9         61  
77 9         121 $w->endTag($tag);
78             } else {
79 0         0 $w->emptyTag($tag, @attr);
80             }
81 26         116 };
82 26         50 $dumper->($node);
83              
84             # $w->end; # this adds a character return we don't want.
85 26         341 $xml;
86             }
87              
88             # utility for intelligent use of cdata.
89             sub encode_xml {
90 26     26 0 128 my ($w, $data, $nocdata) = @_;
91 26 50       60 return unless defined($data);
92 26 100 66     212 if (
93             !$nocdata
94             && $data =~ m/
95             <[^>]+> ## HTML markup
96             | ## or
97             &(?:(?!(\#([0-9]+)|\#x([0-9a-fA-F]+))).*?);
98             ## something that looks like an HTML entity.
99             /x
100             ) {
101              
102             # $w->cdata($data); # this was inserting a extra character into returned strings.
103 8         45 my $str = $w->characters($data);
104 8         459 $str =~ s/]]>/]]>/g;
105 8         31 '';
106             } else {
107 18         51 $w->characters($data);
108             }
109             }
110              
111             1;
112              
113             __END__