File: XML.pm

package info (click to toggle)
libcatmandu-xml-perl 0.17-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 216 kB
  • sloc: perl: 387; xml: 28; makefile: 2; sh: 1
file content (120 lines) | stat: -rw-r--r-- 2,722 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package Catmandu::Exporter::XML;

our $VERSION = '0.17';

use Catmandu::Sane;
use Moo;

use XML::Struct::Writer;
use Catmandu::Util qw(io);

with 'Catmandu::Exporter';

has directory => (
    is  => 'ro',
    isa => sub { die "output directory not found\n" unless -d $_[0] },
);
has field => ( 
    is      => 'ro',
    lazy    => 1, 
);
has filename  => ( 
    is => 'ro', 
    lazy    => 1, 
    default => sub { defined $_[0]->directory ? '_id' : undef }
);

our @WRITER_OPTIONS;
BEGIN {
    @WRITER_OPTIONS = qw(attributes xmldecl encoding version standalone pretty);
    has $_ => (is => 'rw') for @WRITER_OPTIONS;
}

has writer => (
    is        => 'ro',
    predicate => 1,
    lazy      => 1,
    default   => sub {
        XML::Struct::Writer->new( 
            to => $_[0]->fh,
            map { $_ => $_[0]->$_ } grep { defined $_[0]->$_ } 
            @WRITER_OPTIONS
        );
    },
);

sub add {
    my ($self, $data) = @_;

    my $xml = defined $self->field ? $data->{$self->field} : $data;

    if (defined $self->directory) {
        my $filename = $data->{$self->filename};
        $filename .= '.xml' if $filename !~ /\.xml/;
        if ($filename !~ qr{^[^/\0]+$}) {
            $self->log->error("disallowed filename: $filename");
            # TODO: check for disallowed characters on non-Unix systems
            return;
        } else {
            my $filename = $self->directory . "/$filename";
            $self->log->debug("exporting XML to $filename");
            $self->writer->handler->{fh} = io( $filename, mode => 'w' ); 
                # TODO: binmode => $self->writer->encoding // ':utf8'
            $self->writer->write($xml);
            $self->writer->handler->fh->close;
        }
    } else {
        $self->writer->write($xml);
    }
}

1;
__END__

=head1 NAME

Catmandu::Exporter::XML - serialize and export XML documents

=head1 DESCRIPTION

This L<Catmandu::Exporter> exports items serialized as XML. Serialization is
implemented based on L<XML::Struct::Writer::Stream>. By default, each item is
written to STDOUT.

=head1 CONFIGURATION

=over

=item attributes

=item xmldecl

=item encoding

=item version

=item standalone

=item pretty

These options are passed to L<XML::Struct::Writer>. The target (option C<to>)
is based on L<Catmandu::Exporter>'s option C<fh> or C<file>.

=item field

Take XML from a given field of each item, e.g. field C<xml> as following:

    { xml => [ root => { xmlns => 'http://example.org/' }, [ ... ] ] }

=item directory

Serialize to multiple files in a given directory.

=item filename

Field to take filenames from if option C<directory> is set. Defaults to C<_id>.
The file extension C<.xml> is appended unless given.

=back

=cut