I have a bunch of legacy modules I want to convert to being Moose-based. The modules currently have "toXML" methods, which are hand-coded using XML::LibXML.
Is there a module or technique for serializing Moose objects to XML?
I have looked at MooseX::Storage, but that handles JSON, YAML, and Storage, not XML. A google search for Moose and XML yields lots of references to XML::Rabbit, which seems to be good for parsing XML into Moose classes, but there's not a lot out there for taking Moose objects and serializing them to XML.
The 6-year-old thread at http://grokbase.com/t/perl/moose/11akp809sr/java-annotation-net-attributes-in-moose is extremely close to what I want to do, but there doesn't seem to be any followup on it.
The MooseX::Storage serializes data in
JSON
by using MooseX::Storage::Format::JSON role, which is a good example for how to plug in other formats. I cannot see any roles forXML
serialization, but it is easy to write your own and the module provides a hook for it.This minimal example shows how to write a role and consume (use) it in a class. A role is a class-like package which never gets instantiated on its own but is rather absorbed by classes that use it. It can be used by multiple classes. At the end it is shown how to hook the new role into
MooseX::Storage
and thus use that in your class.It uses XML::Dumper for serialization itself, mostly as a placeholder for custom code (if needed).
Point.pm
The only specific statement here is the line
with 'SerializeXML';
SerializeXML.pm
The construction of an object from
XML
should be done vianew
, and/or as a class method.main
This prints
Methods for writing to and loading from a file can be added. But now you have a ready role which can be hooked to
MooseX::Storage
, as shown below.I don't know nor have tested how well
XML::Dumper
works withMoose
. Please test and if it doesn't cut it for your needs swap calls to it with your own code that does what you need.The remaining step is to integrate this in
MooseX::Storage
, if desired.There are two necessary small changes to make in the above code. Use role in
Point
asand rename
to_xml
andfrom_xml
tofreeze
andthaw
(or add these, with same code).Then you can use
store
andload
inmain
in order to write to$file
and load from itThe syntax
=PackageName
is for a namespace prefix other thanMooseX::Storage::Format::
For roles see Moose::Manual::Roles and Moose::Cookbook::Roles:: namespace (examples).
So one of the reasons why
MooseX::Storage
doesn't have a XML storage format is that as you've discovered, most people have a legacy format for XML that they need to write to. XML and Perl actually have very different ways of representing data and figuring that out the right way to translate between the two isn't actually something you can do automatically.You're not going to find an "off the shelf" option per-se. As simbabque mentions in a comment if you have or can easily build a Schema for your data then
XML::Compile
or 'XML::Pastormight work for you (
XML::Compileis better maintained). If you're willing to do some grunt work
XML::Toolkitis designed to translate an example document into a series of Moose classes that it can then later re-serialize. However I haven't touched
XML::Toolkit` in a long time so YMMV on what it needs to get running.I think that ultimately you'll find that the simplest solution is the one you already have, hand-built
toXML
methods. Moose doesn't stop you from doing that, and in fact gives you a bunch of tools to figure out how to make it more maintainable. Look at how MooseX::Storage itself is implemented to see a good path forward.