如何将Moose对象序列化为XML?

时间:2017-02-26 03:39:22

标签: xml perl serialization moose

我有一堆遗留模块,我想转换为基于Moose的模块。这些模块目前有" toXML"方法,使用XML :: LibXML手动编码。

是否有用于将Moose对象序列化为XML的模块或技术?

我看过MooseX :: Storage,但它处理的是JSON,YAML和Storage,而不是XML。谷歌对Moose和XML的搜索产生了大量对XML :: Rabbit的引用,这似乎很适合将XML解析为Moose类,但是在那里采用Moose对象并将它们序列化为XML并不是很多。

http://grokbase.com/t/perl/moose/11akp809sr/java-annotation-net-attributes-in-moose的6岁主题与我想做的非常接近,但似乎没有任何跟进。

2 个答案:

答案 0 :(得分:3)

MooseX::Storage使用MooseX::Storage::Format::JSON 角色序列化JSON中的数据,这是如何插入其他格式的一个很好的示例。我看不到XML序列化的任何角色,但是编写自己的角色很简单,模块为它提供了一个钩子。

这个最小的例子展示了如何在类中编写角色使用(使用)它。角色是一个类似于类的包,它永远不会自己实例化,而是被使用它的类所吸收。它可以由多个类使用。最后,它将展示如何将新角色挂钩到MooseX::Storage,从而在您的班级中使用它。

它使用XML::Dumper进行序列化,主要用作自定义代码的占位符(如果需要)。

<强> Point.pm

package Point;    

use Moose;

use overload  q("") => sub { 
    my $self = shift; 
    return '(' . $self->x . ', ' . $self->y . ')' 
};  

has 'x' => (is => 'rw', isa => 'Int', required => 1, default => 0); 
has 'y' => (is => 'rw', isa => 'Int', required => 1, default => 0); 

with 'SerializeXML';

sub BUILD { print "Created a Point $_[0]\n" }

__PACKAGE__->meta->make_immutable;    
1;

此处唯一具体的陈述是with 'SerializeXML';

<强> SerializeXML.pm

package SerializeXML;

use Moose::Role;    
use XML::Dumper;

sub to_xml {
    my ($self) = shift;
    return XML::Dumper->new->pl2xml($self);  # or use custom code
}

sub from_xml {
    my ($self, $xml) = @_; 
    return XML::Dumper->new->xml2pl($xml);
}

no Moose::Role;
1;

XML中对象的构造应通过new和/或作为类方法完成。

主要

use warnings;
use strict;

use Point;

my $pt = Point->new(x => 10, y => 12);

my $obj_xml = $pt->to_xml;
print "$obj_xml\n";

my $obj = $pt->from_xml($obj_xml);
print "Object via role: $obj\n";

打印

Created a Point (10, 12)
<perldata>
 <hashref blessed_package="Point" memory_address="0x1691438">
  <item key="x">10</item>
  <item key="y">12</item>
 </hashref>
</perldata>
Object via role: (10, 12)

可以添加写入和加载文件的方法。但是现在你有一个可以挂钩到MooseX::Storage的准备好的角色,如下所示。

我不知道也不测试XML::DumperMoose的合作程度。请测试,如果没有根据您的需要切换它,请使用您自己的代码交换调用,以满足您的需求。

如果需要,剩下的步骤是将其整合到MooseX::Storage中。

在上面的代码中有两个必要的小改动。使用Point中的角色作为

use MooseX::Storage;

with Storage(format => '=SerializeXML', io => 'File');

并将to_xmlfrom_xml重命名为freezethaw(或使用相同的代码添加这些内容)。

然后,您可以在store中使用loadmain来写入$file并从中加载

$pt->store($file);
my $pt_new = Point->load($file);

语法=PackageName用于除MooseX::Storage::Format::

之外的名称空间前缀

对于角色,请参阅Moose::Manual::RolesMoose::Cookbook::Roles::命名空间(示例)。

答案 1 :(得分:1)

因此,MooseX::Storage没有XML存储格式的原因之一是,正如您所发现的那样,大多数人都有他们需要写入的XML遗留格式。 XML和Perl实际上有非常不同的方式来表示数据,并确定在两者之间进行翻译的正确方法实际上是你可以自动完成的事情。

你不会找到现成的#34;&#34;选项本身。正如simbabque在评论中提到的那样,如果您已经或可以轻松地为您的数据构建S​​chema,那么XML::Compile或&#39; XML :: Pastor might work for you ( XML ::编译is better maintained). If you're willing to do some grunt work XML ::工具包is 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`在 long 时间内,因此YMMV需要运行它。

我认为最终您会发现最简单的解决方案是您已经拥有的,手工构建的toXML方法。 Moose并没有阻止你这样做,事实上它为你提供了一系列工具来弄清楚如何让它更易于维护。看看MooseX :: Storage本身是如何实现的,以便看到一条好的前进道路。