NAME

XML::FromPerl - Generate XML from simple Perl data structures

SYNOPSIS

use XML::FromPerl qw(xml_from_perl);

my $doc = xml_from_perl
  [ Foo => { attr1 => val1, attr2 => val2},
    [ Bar => { attr3 => val3, ... },
      [ '!--', 'some comment, indicated by tag name "!--"' ],
      [ Bar => { ... },
      "Some Text here",
      [Doz => { ... },
        [ Bar => { ... }, [ ... ] ] ] ] ] ];

$doc->toFile("foo.xml");
# ->  <Foo attr1="val1" attr2="val2">
#         <Bar attr3="val3">
#             <!--some comment...-->
#             ...
#         </Bar>
#     </Foo>

DESCRIPTION

This module is able to generate XML described using simple Perl data structures.

XML nodes are declared as arrays where the first slot is the tag name, the second is a HASH containing tag attributes and the rest are its children. Perl scalars are used for text sections.

EXPORTABLE FUNCTIONS

xml_from_perl $data

Converts the given perl data structure into a XML::LibXML::Document object.

If $data is undefined, the document will have no root element or other contents. A warning in category 'XML::FromPerl::undefined' will be issued.

xml_node_from_perl $doc, $data

Converts the given perl data structure into a XML::LibXML::Node object linked to the document passed.

If $data is undefined, or is an arrayref including any undefined entries, the undefined entries will be ignored. A warning in category 'XML::FromPerl::undefined' will be issued for each undef item processed.

NOTES

Namespaces

I have not made my mind yet about how to handle XML namespaces other than stating them explicitly in the names or setting the xmlns attribute.

Attribute order

If attribute order is important to you, declare then using Tie::IxHash:

For instance:

use Tie::IxHash;
sub attrs {
  my @attrs = @_;
  tie my(%attrs), 'Tie::Hash', @attrs;
  \%attrs
}

my $doc = xml_from_perl [ Foo => attrs(attr1 => val1, attrs2 => val2), ...];

Otherwise attributes are sorted in lexicographical order.

Memory usage

This module is not very memory efficient. At some point it is going to keep in memory both the original perl data structure and the XML::LibXML one.

Anyway, nowadays that shouldn't be a problem unless your data is really huge.

Comments

Any attributes or children of a comment node will be ignored. So, for example,

[ '!--',
    { attr => 'val' },
    [ Foo => { attr => "hello" } ]
]

will produce

<!---->

not

<!--<Foo attr="hello"/>-->

This is due to a limitation of XML::LibXML: XML::LibXML::Comment::appendChild() is a no-op.

Any text elements in a comment node will be joined together by the value of $,, or a single space if $, is undefined. For example, if $, eq '#',

[ '!--', qw(hello there world) ]

will produce

<!--hello#there#world-->

SEE ALSO

XML::LibXML, XML::LibXML::Document, XML::LibXML::Node.

Other modules for generating XML are XML::Writer and XML::Generator. Check also XML::Compile.

A related PerlMonks discussion: http://www.perlmonks.org/?node_id=1195009.

COPYRIGHT AND LICENSE

Copyright (C) 2017, 2019 by Salvador Fandiño <sfandino@yahoo.com> and Christopher White <cxw@cpan.org>.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.24.1 or, at your option, any later version of Perl 5 you may have available.