File Coverage

blib/lib/Catmandu/Exporter/XSD.pm
Criterion Covered Total %
statement 22 22 100.0
branch 2 4 50.0
condition 2 3 66.6
subroutine 8 8 100.0
pod 0 1 0.0
total 34 38 89.4


line stmt bran cond sub pod time code
1             package Catmandu::Exporter::XSD;
2              
3 1     1   371492 use Catmandu::Sane;
  1         2  
  1         9  
4              
5             our $VERSION = '0.05';
6              
7 1     1   199 use Moo;
  1         2  
  1         7  
8 1     1   331 use Catmandu;
  1         3  
  1         6  
9 1     1   598 use Catmandu::XSD;
  1         4  
  1         627  
10              
11             with 'Catmandu::Exporter';
12              
13             has 'root' => (is => 'ro' , required => 1);
14             has 'schemas' => (is => 'ro' , required => 1);
15             has 'mixed' => (is => 'ro' , default => sub { 'ATTRIBUTES' });
16             has 'prefixes' => (is => 'ro');
17              
18             has 'split' => (is => 'ro');
19             has 'split_pattern' => (is => 'ro' , default => sub { '%s.xml' } );
20             has 'split_directory' => (is => 'ro' , default => sub { '.' });
21              
22             has 'template_before' => (is => 'ro');
23             has 'template' => (is => 'ro');
24             has 'template_after' => (is => 'ro');
25              
26             has 'tt' => (is => 'lazy');
27             has 'xsd' => (is => 'lazy');
28              
29             sub BUILD {
30 3     3 0 36 my ($self,$args) = @_;
31              
32             die "split and template can't be set at the same time"
33 3 50 66     34 if (exists $args->{split} && exists $args->{template});
34             }
35              
36             sub _build_xsd {
37 3     3   30 my $self = $_[0];
38 3         61 return Catmandu::XSD->new(
39             root => $self->root ,
40             schemas => $self->schemas ,
41             mixed => $self->mixed ,
42             prefixes => $self->prefixes ,
43             );
44             }
45              
46             sub _build_tt {
47 1     1   11 my $self = $_[0];
48              
49 1 50       9 if ($self->template) {
50 1         19 Catmandu->exporter(
51             'Template',
52             fh => $self->fh ,
53             template_before => $self->template_before ,
54             template => $self->template ,
55             template_after => $self->template_after ,
56             );
57             }
58             }
59              
60             sub add {
61             my ($self, $data) = @_;
62              
63             my $xml = $self->xsd->to_xml($data);
64              
65             if ($self->template) {
66             $xml =~ s{<\?xml version="1.0" encoding="UTF-8"\?>}{};
67             $data->{xml} = $xml;
68             $self->tt->add($data);
69             }
70             elsif ($self->split) {
71             my $id = $data->{_id} // $self->count;
72             my $directory = $self->split_directory;
73             my $filename = sprintf $self->split_pattern , $id;
74             local(*F);
75 1     1   8 open(F,'>:encoding(utf-8)',"$directory/$filename")
  1         2  
  1         6  
76             || die "failed to open $directory/$filename for writing : $!";
77             print F $xml;
78             close(F);
79             }
80             else {
81             $self->fh->print($xml);
82             }
83             }
84              
85             sub commit {
86             my $self = $_[0];
87              
88             if ($self->template && $self->count) {
89             $self->tt->commit;
90             }
91              
92             1;
93             }
94              
95             1;
96              
97             __END__
98              
99             =pod
100              
101             =head1 NAME
102              
103             Catmandu::Exporter::XSD - Export and validate XML documents
104              
105             =head1 SYNOPSIS
106              
107             # Convert one shiporder YAML to XML
108             catmandu convert YAML to XSD --root '{}shiporder'
109             --schemas demo/order/*.xsd < shiporder.YAML
110              
111             # Same as above but store multiple shiporders in the YAML into a separate file
112             catmandu convert YAML to XSD --root '{}shiporder'
113             --schemas demo/order/*.xsd
114             --split 1
115             < shiporder.YAML
116              
117             # Same as above but use template toolkit to pack the XML into an container
118             # (The xml record is stored in the 'xml' key which can be retrieved in the
119             # template by [% xml %])
120             catmandu convert YAML to XSD --root '{}shiporder'
121             --schemas demo/order/*.xsd
122             --template_before t/xml_header.tt
123             --template t/xml_record.tt
124             --template t/xml_footer.tt
125             < shiporder.YAML
126              
127             use Catmandu;
128              
129             # Print to STDOUT
130             my $exporter = Catmandu->exporter('XSD',
131             root => ...
132             schemas => ...
133             );
134              
135             $exporter->add_many($arrayref);
136             $exporter->add_many($iterator);
137             $exporter->add_many(sub { });
138             $exporter->add($hashref);
139              
140             $exporter->commit;
141              
142             =head1 DESCRIPTION
143              
144             This is a L<Catmandu::Exporter> for converting Perl into valided XML documents
145             using an XSD schema file.
146              
147             =head1 CONFIGURATION
148              
149             =over
150              
151             =item file
152              
153             Write output to a local file given by its path. Alternatively a scalar
154             reference can be passed to write to a string.
155              
156             =item fh
157              
158             Write output to an L<IO::Handle>. If not specified, L<Catmandu::Util::io> is used to
159             create the output stream from the C<file> argument or by using STDOUT.
160              
161             =item split
162              
163             Optional. Don't write to the file (or STDOUT) and split the output documents into
164             one or more files. E.g.
165              
166             catmandu ... to XSD --root ... --schemas ... --split 1 < data
167              
168             =item split_pattern
169              
170             Optional. Use a FORMAT as template for naming output files. Uses the '_id' field in
171             the data or an incremental counter as input. E.g.
172              
173             # Creates 000001.xml , 000002.xml, etc
174             catmandu ... to XSD --root ... --schemas ... --split 1 --split_pattern '%-6.6d.xml' < data
175              
176             =item split_directory
177              
178             Optional. Specify the directory in which the split files need to be written.
179              
180             =item template
181              
182             Optional. A template toolkit template to be used for creating each XML output record. Gets as input
183             the input data plus the XML serialized form in the 'xml' field.
184              
185             =item template_before
186              
187             Optional. The template toolkit template to be used as XML header.
188              
189             =item template_after
190              
191             Optional. The template toolkit template to be used as XML footer.
192              
193             =item fix
194              
195             An ARRAY of one or more fixes or file scripts to be applied to imported items.
196              
197             =item root
198              
199             Required. The name (and namespace) of the root element of the XML document. E.g.:
200              
201             {}shiporder
202             {http://www.loc.gov/mods/v3}mods
203             {urn:isbn:1-931666-22-9}ead
204              
205             =item schemas
206              
207             Required. An array or comma separated list of XSD schema locations.
208              
209             =item prefixes
210              
211             Optional. An array or comma delimited string of namespace prefixes to be used
212             hand handling XML files. E.g.
213              
214             # On the command line:
215             catmandu ... --prefixes ead:urn:isbn:1-931666-22-9,...
216              
217             # In Perl
218             prefixes => [
219             ead => 'urn:isbn:1-931666-22-9' ,
220             ... => ...
221             ]
222              
223             =item mixed
224              
225             Optional. The handling of mixed element content. One of ATTRIBUTES (default),
226             TEXTUAL, STRUCTURAL, XML_NODE, XML_STRING, CODE reference. See also
227             L<Catmandu::XSD> and L<XML::Compile::Translate::Reader>
228              
229             =back
230              
231             =head1 METHODS
232              
233             Every L<Catmandu::Importer> is a L<Catmandu::Iterable> all its methods are
234             inherited.
235              
236             =head1 SEE ALSO
237              
238             L<Catmandu::Exporter>, L<Catmandu::XSD> , L<Template>
239              
240             =head1 AUTHOR
241              
242             Patrick Hochstenbach , C<< patrick.hochstenbach at ugent.be >>
243              
244             =head1 LICENSE AND COPYRIGHT
245              
246             This program is free software; you can redistribute it and/or modify it
247             under the terms of either: the GNU General Public License as published
248             by the Free Software Foundation; or the Artistic License.
249              
250             See L<http://dev.perl.org/licenses/> for more information.
251              
252             =cut