File Coverage

blib/lib/Text/vFile/toXML.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             package Text::vFile::toXML;
2              
3 3     3   96126 use strict;
  3         6  
  3         104  
4 3     3   13 use warnings;
  3         7  
  3         140  
5              
6             =head1 NAME
7              
8             Text::vFile::toXML - Convert vFiles into equivalent XML
9              
10             =head1 VERSION
11              
12             Version 0.04
13              
14             =cut
15              
16             our $VERSION = '0.04';
17              
18 3     3   17 use Carp qw(croak);
  3         4  
  3         176  
19 3     3   2434 use Text::vFile::asData;
  3         21981  
  3         28  
20 3     3   4397 use XML::Quick;
  0            
  0            
21              
22             use base qw(Exporter);
23             our @EXPORT_OK = qw(to_xml xCalNS);
24              
25             our %attrs = qw(language xml:lang);
26             our $xCalNS = 'urn:ietf:params:xml:ns:xcal';
27              
28             =head1 SYNOPSIS
29              
30             This module converts iCalendar (iCal : generically, vFile) files into their
31             (equivalent) XML (xCalendar / xCal) representation, according to Royer's IETF
32             Draft (L).
33              
34             # Enable functional interface
35             use Text::vFile::toXML qw(to_xml);
36              
37             # Input filename
38             my $arg = "input.file";
39             my $a = Text::vFile::toXML->new(filename => $arg)->to_xml;
40             my $b = Text::vFile::toXML->new(filehandle =>
41             do { open my $fh, $arg or die "can't open ics: $!"; $fh }
42             )->to_xml;
43              
44             use Text::vFile::asData; # to make the functional example work
45             my $data =
46             Text::vFile::asData->new->parse(
47             do {
48             open my $fh, $arg
49             or die "Can't open vFile: $!"; $fh
50             }
51             );
52             my $c = Text::vFile::toXML->new(data => $data)->to_xml;
53              
54             # Use functional interface
55             my $d = to_xml($data);
56              
57             # Now ($a, $b, $c, $d) all contain the same XML string.
58              
59             =head1 EXPORT
60              
61             No functions are exported by default; you can choose to import the 'to_xml'
62             function if you wish to use the functional interface.
63              
64             =head1 METHODS
65              
66             =head2 new
67              
68             Creates a new Text::vFile::toXML object; takes a list of key-value pairs for initialization, which must contain exactly one of the following:
69              
70             filehandle => (filehandle object)
71             filename => (string)
72             data => (Text::vFile::asData struct)
73              
74             =cut
75              
76             sub new {
77             my ($type, %args) = @_;
78              
79             croak "Must provide exactly one of (filehandle, filename, or data)"
80             unless +@{[ grep defined, @args{qw(filehandle filename data)} ]} == 1;
81              
82             $args{_data} = delete $args{data}
83             || Text::vFile::asData->new->parse(
84             $args{filehandle} || ($args{filename} &&
85             do { open my $fh, $args{filename} or die; $fh }
86             ));
87            
88             bless \%args, $type
89             }
90              
91             =head2 to_xml
92              
93             Wraps the convert() function; returns an XML string. Can be called as an
94             instance method (OO-style) or as a function (functional style), in which case
95             it takes a Text::vFile::asData-compatible data structure as its only parameter.
96              
97             =cut
98              
99             sub to_xml {
100             xml({ convert($_[0]->{_data}{objects} || $_[0]->{objects}) },
101             { root => 'iCalendar', attrs => { 'xmlns:xCal' => $xCalNS } })
102             }
103              
104             =head2 convert
105              
106             Recursively converts Text::vFile::asData structures to XML::Quick-compatible
107             ones.
108              
109             =cut
110              
111             sub convert {
112             my ($data) = @_;
113             my %result;
114              
115             for my $object (@$data) {
116             my ($props, $objects, $type) = @$object{qw(properties objects type)};
117              
118             push @{ $result{lc $type} }, +{
119             convert($objects),
120             map {
121             my $propname = $_;
122             lc $propname => [ map { my ($p, $v) = @$_{qw(param value)}; +{
123             _cdata => $v,
124             _attrs => +{ map { $attrs{lc $_} || lc $_ => $p->{$_} } keys %$p } }
125             } @{ $props->{$propname} } ]
126             } keys %$props
127             };
128             }
129              
130             return %result;
131             }
132              
133             =head1 AUTHOR
134              
135             Darren Kulp, C<< >>
136              
137             =head1 BUGS
138              
139             Probably. Email me at the address above with bug reports.
140              
141             =head1 ACKNOWLEDGEMENTS
142              
143             The L and L modules proved very useful, to the
144             point of nearly trivializing this module.
145              
146             =head1 COPYRIGHT & LICENSE
147              
148             Copyright 2006 Darren Kulp.
149              
150             This program is released under the terms of the BSD license.
151              
152             =cut
153              
154             1; # End of Text::vFile::toXML
155             __END__