2017-02-26 34 views
3

我有一堆遺留模塊,我想轉換爲駝鹿爲基礎。這些模塊目前有「toXML」方法,這些方法使用XML :: LibXML進行手動編碼。如何將Moose對象序列化爲XML?

有沒有模塊或技術用於序列化駝鹿對象到XML?

我看過MooseX :: Storage,但它處理JSON,YAML和存儲,而不是XML。谷歌搜索Moose和XML會產生大量對XML :: Rabbit的引用,這似乎很適合將XML解析爲Moose類,但沒有太多將Moose對象和序列化到XML的方法。

http://grokbase.com/t/perl/moose/11akp809sr/java-annotation-net-attributes-in-moose 6歲的線程是非常接近我想要做的,但似乎沒有任何後續行動。

+1

[MooseX :: Storage](http://search.cpan.org/~ether/MooseX-Storage-0.52/lib/MooseX/Storage.pm)通過使用[MooseX :: Storage :: Format :: JSON](http://search.cpan.org/~ether/MooseX-Storage-0.52/lib/MooseX/Storage/Format/JSON.pm)的作用。從我所看到的,它是我們那裏唯一的'MooseX :: Storage :: Format'序列化角色。也許寫你自己的? 'Format :: JSON'的代碼是幾十行(使用一個模塊)。我不知道你需要序列化的是什麼,但是可能[XML :: Dumper](http://search.cpan.org/~mikewong/XML-Dumper-0.81/Dumper.pm)可以提供幫助。它聲稱能夠處理對象。 – zdim

+0

@zdim,Re「*從我所看到的,它是唯一的MooseX :: Storage :: Format序列化角色,我們在那裏*」,MooseX :: Storage :: Format :: JSON,... :: YAML和。 .. ::可存儲所有來與MooseX ::存儲。 – ikegami

+0

@Blaise Pascal,所以編寫MooseX :: Storage :: Format :: XML。 – ikegami

回答

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施工中應通過完成,和/或作爲類方法。

主要

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"; 

#$obj->x(0.12); # fails as it should (only Int allowed) 

這用於寫入和加載從文件中可以添加打印

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_xmlfreezethaw(或添加這些,用相同的代碼)。

然後你可以使用storeloadmain以從中

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

語法=PackageName是不是MooseX::Storage::Format::

以外的命名空間前綴寫入$file和負載的作用看Moose::Manual::RolesMoose::Cookbook::Roles::命名空間(示例)。

+0

這是一個非常好的指南。如果特別需要XML,我們可以假設OP知道他們圍繞XML的方式,所以不用XML :: Dumper,也許可以使用XML :: Compile。如果他們編寫實際的XML模式並將其與數據一起提供給XML :: Compile,他們甚至可以輕鬆地接受來自外部數據源的數據,直接通過發佈模式來創建對象。 – simbabque

+1

@simbabque謝謝。它本來是基本的。我不想觸及'XML'處理,因爲這是另一個問題。這是你提供的一個好主意。也許OP應該詢問'XML'是一個單獨的問題,並描述他們在做什麼以及他們爲什麼選擇這種格式。 – zdim

+0

我正在處理遺留代碼/遺留數據,所以我沒有選擇XML格式,只是從十多二十年前做出這個決定的人那裏繼承了它。不幸的是,這意味着不能使用'XML :: Dumper',因爲它不會轉儲正確的格式。 現有的'MooseX :: Storage :: Format'模塊基本上封裝了一個像XML :: Dumper這樣的現有的自卸車,但是不能對這個格式進行任何控制。這不是我需要的。 –

1

因此,MooseX::Storage沒有XML存儲格式的原因之一是,正如您發現的那樣,大多數人擁有需要寫入的XML格式。 XML和Perl實際上具有非常不同的表示數據的方式,並且找出在兩者之間進行轉換的正確方法實際上並不是您可以自動執行的操作。

本身不會找到「現成的」選項。正如simbabque在評論中提到的,如果您已經或可以輕鬆地爲您的數據構建架構,那麼XML::Compile或'XML :: Pastor might work for you ( XML :: Compile is better maintained). If you're willing to do some grunt work XML :: Toolkit 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 time so YMMV關於它需要運行的東西。

我認爲最終你會發現最簡單的解決方案就是你已經擁有的那種方法,手工製作toXML方法。穆斯並沒有阻止你這樣做,事實上,它給你提供了一些工具來弄清楚如何使它更容易維護。看看MooseX :: Storage本身是如何實現的,以便看到一條好的路徑。