如何将 Moose 对象序列化为 XML? [英] How do I serialize Moose objects to XML?

查看:29
本文介绍了如何将 Moose 对象序列化为 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::DumperMoose 的配合效果如何.请进行测试,如果它不能满足您的需求,请使用您自己的代码来满足您的需求.

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_xmlfrom_xml 重命名为freezethaw(或添加这些,使用相同的代码).

and rename to_xml and from_xml to freeze and thaw (or add these, with same code).

然后你可以在 main 中使用 storeload 来写入 $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::RolesMoose::Cookbook::Roles:: 命名空间(示例).

For roles see Moose::Manual::Roles and Moose::Cookbook::Roles:: namespace (examples).

这篇关于如何将 Moose 对象序列化为 XML?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆