如何将 Moose 对象序列化为 XML? [英] How do I serialize Moose objects to XML?
问题描述
我有一堆遗留模块想要转换为基于 Moose 的模块.这些模块目前有toXML"方法,这些方法是使用 XML::LibXML 手工编码的.
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.
是否有将 Moose 对象序列化为 XML 的模块或技术?
Is there a module or technique for serializing Moose objects to XML?
我看过 MooseX::Storage,但它处理的是 JSON、YAML 和存储,而不是 XML.谷歌搜索 Moose 和 XML 会产生大量对 XML::Rabbit 的引用,这似乎有助于将 XML 解析为 Moose 类,但用于获取 Moose 对象并将它们序列化为 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.
http://grokbase.com/t/perl/moose/11akp809sr/java-annotation-net-attributes-in-moose 非常接近我想要做的,但似乎没有任何后续行动.
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.
推荐答案
MooseX::Storage 使用 MooseX::Storage::Format::JSON role,这是一个很好的例子如何插入其他格式.我看不到 XML
序列化的任何角色,但是编写自己的代码很容易,并且模块为它提供了一个钩子.
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 for XML
serialization, but it is easy to write your own and the module provides a hook for it.
这个最小的例子展示了如何在一个类中编写一个角色和消费(使用)它.角色是一个类似类的包,它永远不会自己实例化,而是被其他类吸收.它旨在提供可以轻松插入"计算机的功能.在,并被多个类使用.最后展示了如何将新角色挂钩到 MooseX::Storage
中,并在您的类中使用它.
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 other classes. It is meant to provide functionality that can be easily "plugged" in, and used by multiple classes. At the end it is shown how to hook the new role into MooseX::Storage
and so use it in your class.
它使用 XML::Dumper 进行序列化本身,主要用作自定义代码的占位符(如果需要).
It uses XML::Dumper for serialization itself, mostly as a placeholder for custom code (if needed).
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';
The only specific statement here is the line 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
和/或作为类方法完成.
The construction of an object from XML
should be done via new
, and/or as a class method.
主要
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
的就绪角色,如下所示.
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.
我不知道也没有测试过 XML::Dumper
与 Moose
的配合效果如何.请进行测试,如果它不能满足您的需求,请使用您自己的代码来满足您的需求.
I don't know nor have tested how well XML::Dumper
works with Moose
. 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.
如果需要,剩下的步骤是将其集成到 MooseX::Storage
中.
The remaining step is to integrate this in MooseX::Storage
, if desired.
在上面的代码中有两个必要的小改动.在 Point
中使用 role as
There are two necessary small changes to make in the above code. Use role in Point
as
use MooseX::Storage;
with Storage(format => '=SerializeXML', io => 'File');
并将to_xml
和from_xml
重命名为freeze
和thaw
(或添加这些,使用相同的代码).
and rename to_xml
and from_xml
to freeze
and thaw
(or add these, with same code).
然后你可以在 main
中使用 store
和 load
来写入 $file
并从它
Then you can use store
and load
in main
in order to write to $file
and load from it
$pt->store($file);
my $pt_new = Point->load($file);
语法 =PackageName
适用于 MooseX::Storage::Format::
有关角色,请参阅 Moose::Manual::Roles 和 Moose::Cookbook::Roles:: 命名空间(示例).
For roles see Moose::Manual::Roles and Moose::Cookbook::Roles:: namespace (examples).
这篇关于如何将 Moose 对象序列化为 XML?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!