Article View: cn.bbs.comp.xml
Article #216���� Perl ������Ա�� XML���� 1 ����(ת��)
From: <Test/>
Date: Tue, 27 Apr 2010 15:34
Date: Tue, 27 Apr 2010 15:34
380 lines
26323 bytes
26323 bytes
��ϵ��Ϊ��Ҫ XML �� Perl ���ٽ�������Ŀ�����Ա�ṩ��һ��ָ�ϡ����������£�ֻ��Ҫ XML::Simple ��һ�ֹ��߾��ܹ��� XML ���ɵ� Perl Ӧ�ó����С��� 1 ���ֽ����������� XML::Simple�����ʹ�����Լ�������Ҫ��ʲô������ Perl ��ʹ�� XML �������֮��ϵ���е�������ƪ���½�����������ܡ�
���
�����ǹ��� Perl �� XML �ķ���ֵ�ϵ�����µĵ�һƪ����Ҫ��ע XML::Simple������ Perl ����Ա����һ��ʹ�� XML �����Ǵ������ļ����ղ�����Ҫ������������д����ȡ����IJ����һ�и��� Perl Ҫʹ�� XML::Simple���ڶ��н�һ����������Ϊ�ļ��е�һ��ֵ�����������ṩ�����ļ�����ƣ�XML::Simple ��������ܻ��IJ²⡣
��Ϊһ�����ӵ�ʾ������Ҫ�о�һ�������̵�Ӧ�ó�������һ���У���ѧϰ��μ��ؽ� XML �ļ�����һ����λ��� Perl ��ݽṹ�����������ɢ�е���ϣ������Ľ��� Perl ��μ���ת��������ԭ XML �ĵ��а����Ϣ��Ȼ���Ը�����ʽ����Ϣд��ȥ��
������� XML::Simple ��һЩ���ơ�����������ƪ���µ����⣺����Ľ�����ʹ�ø����߶� XML ����ʽ����ת�����Լ��� DOM �������ڴ�����ʽ�� XML ���д��л���
������Ҫ��Էdz���Ϥ Perl �� Perl ����Ա�����Ƕ� XML ר��Ҳ���ã������������Ը�����Եķ�ʽ���� XML �ĵ���
��ʼ
�ڿ�ʼ֮ǰ����Ҫ��װ Perl�����û�а�װ Perl����μ� �ο����� �е����ӡ�
����������Ҫ XML::Simple�����ʹ�� UNIX �� Linux����ô���ķ�����ʹ�� cpan �� CPAN ������ǡ����ȣ�ʹ���嵥 1 �е������ڻ����ϰ�װ cpan��һ����˵��Ӧ����Ϊ���û�ִ������������Ӷ��� Perl ģ��ɹ������û�ʹ�á�
�嵥 1. ��װ cpan����� XML::Simple
$ perl -MCPAN -e shell
cpan> ...
cpan> install XML::Simple
cpan> quit
�״����д�����ʱ��Ҫ����ܳ��ĶԻ������� �嵥 1 ������ʡ�ԡ�ijЩ�û��ᷢ�֣��༭�õ��������ļ���/etc/perl/CPAN/Config.pm���ܷ��㡣
Windows �û�ʹ�� PPM ִ�����ƵĹ�̣������û�� PPM����μ� �ο����ϣ�������������£���װģ����������嵥 2 ���ơ�
�嵥 2. Windows��ʹ�� PPM ��� XML::Simple
$ ppm install XML::Simple
cpan �� ppm �����ڰ�װ�ڼ�����������Ӵ洢���ȡ�κ�ȱ�ٵ��������� cpan ���Ⱦ�������������Ϊ ��follow������ô�����Զ��ġ��ڰ�װ�ڼ䣬ģ��һ��ᱻ���룬������ҳ��Ϣ����ỨЩʱ�䣬������ġ�
��һ���Ⱦ�����
XML::Simple �� XML �ĵ�ת��Ϊ��ɢ�к�ɢ����������á�����ζ����Ҫ����˽����á�ɢ�к������� Perl �еĽ������á�������ⷽ����Ҫ��������� �ο����� �о��ʵ� Perl �ο��̡̳�
XML::Simple
Grant McLean �� XML::Simple �������������ܣ��� XML �ı��ĵ�ת��Ϊ Perl ��ݽṹ������ɢ�к��������ϣ����Լ���������ݽṹת���� XML �ı��ĵ���
��Щ���ܾ������ޣ����Ǻ����ã����ǽ������������˵����һ�㡣���ȣ�������δ� XML ��ʽ�������ļ��е�����ݡ�Ȼ���ڸ��ӵı��س����̵�ʾ���У�ѧϰ��ν����ӵĴ��� XML �ļ������ڴ棬�Դ�ͳ XML ���ߣ����� XSLT��������ʵ�ֵķ�ʽ�������ת����������д�ش��̡�
���ڴ���������XML::Simple �ṩ���� Perl �д��� XML ��������ж�����
XML �����ļ�
ȫ��������г���Ա��Ҫ���һ�����⣺��Ҫ���ʶȸ��ӵ�������Ϣ���ݸ����������������в������Щ��Ϣ����̫�鷳�ˡ����Ծ���ʹ�������ļ�����Ϊ XML ��������Ϣ�ı���ʽ�����Ծ������� XML �ļ���ʽ���γɵ��ļ����嵥 3 �������ǽ�ʹ�� XML::Simple ��������ļ���
�嵥 3. �����ļ� part1.xml
<config>
<user>freddy</user>
<passwd>longNails</passwd>
<books>
<book author="Steinbeck" title="Cannery Row"/>
<book author="Faulkner" title="Soldier's Pay"/>
<book author="Steinbeck" title="East of Eden"/>
</books>
</config>
���˹�����֮�⣬XML::Simple ����������̣�XMLin() �� XMLout()��������Ԥ�ϵģ���һ������̶�ȡ XML �ļ�������һ�����á�����ʵ���ݽṹ�����ã��ڶ�������̽���ת��Ϊ XML �ĵ�����ݲ���IJ�ͬ������� XML �ĵ������ַ��ʽ���ļ���ʽ��
XML::Simple ��һЩ�����Ĭ�����ã��������û��ָ�������ļ�����ô Perl ���� part1.pl���嵥 4������ȡ�ļ� part1.xml��
�嵥 4. part1.pl
#!/usr/bin/perl -w
use strict;
use XML::Simple;
use Data::Dumper;
print Dumper (XML::Simple->new()->XMLin());
ִ�� part1.pl ������嵥 5 ��ʾ�������
�嵥 5. part1.pl �����
$VAR1 = {
'passwd' => 'longNails',
'user' => 'freddy',
'books' => {
'book' => [
{
'title' => 'Cannery Row',
'author' => 'Steinbeck'
},
{
'title' => 'Soldier\'s Pay',
'author' => 'Faulkner'
},
{
'title' => 'East of Eden',
'author' => 'Steinbeck'
}
]
}
};
XMLin() ����һ����ɢ�е����á����������ø�ֵ����� $config���Ϳ���ʹ�� $config->{user} ����û���ʹ�� $config->{passwd} ������롣���ļ���ԵĶ���ע���ֻ��һ�д���Ϳ��Զ�ȡ�����ļ�������һ������XML::Simple->new->{user}��
��Ȼ���ڴ��� XML::Simple ʱҪע�⼸�����⣺
* ���ȣ������˸�Ԫ�ص���ơ�
* �ڶ����������ͬ��Ƶ�Ԫ�غϲ���һ�������������á���ˣ���һ����ı����� @{$config->{books}->{book}}[0]->{title}���� ��Cannery Row����
* ��������ͬ��ķ�ʽ�Դ����Ժ���Ԫ�ء�
����ͨ�� XMLin() ��ѡ��ı���Щ��Ϊ������ѡ��ĸ����Ϣ���μ� �ο����� ����������ۡ�
һ�����ӵ�ʾ������̵�
XML::Simple �������ܹ��������ļ����мĽ�����ʵ���ϣ�����Դ��?�ӵĴ��� XML �ļ�����������ת��Ϊ�������ݽṹ����Щ�ṹ�������ʺϽ���ת�������� Perl ���Ƿdz����ģ�����ʹ�ñȽϴ�ͳ�� XML ת�����ߣ����� XSLT���Ǻ�����ɵģ������Dz����ܵġ�
��������һ�ҳ����̵깤����Ҫ��һ�� XML �ļ��м�¼���ڳ������Ϣ������ĵ���һ�������嵥 6 ��ʾ������ϣ����һЩ�ģ�
* Ϊ�˽�ʡ�ռ䣬��������Ԫ�ظ�Ϊ����
* ���۸���� 20%
* �����м۸���ʾΪͬ�����ʽ������ʾ��λС��
* ����������
* �������滻��������
������� Perl �����ģ�������ʶ�� XSLT ����ɼ��㣬���Ծ����� XML::Simple ���������������嵥 6����
�嵥 6. pets.xml �ļ���һ����
<?xml version='1.0'?>
<pets>
<cat>
<name>Madness</name>
<dob>1 February 2004</dob>
<price>150</price>
</cat>
<dog>Maggie</name>
<dob>12 October 2005
<name></dob>
<price>75</price>
<owner>Rosie</owner>
</dog>
<cat>
<name>Little</name>
<dob>23 June 2006</dob>
<price>25</price>
</cat>
</pets>
�����̽��
���ȳ������嵥 7 ����ʹ�� XML::Simple��
�嵥 7. ����ij���
#!/usr/bin/perl -w
use strict;
use XML::Simple;
use Data::Dumper;
my $simple = XML::Simple->new();
my $data = $simple->XMLin('pets.xml');
# DEBUG
print Dumper($data) . "\n";
# END
���������ʹ�� Data::Dumper �鿴���ڴ��ж�����ʲô���ݣ�������嵥 8 ��ʾ��
�嵥 8. ��õ�����
$VAR1 = {
'cat' => {
'Little' => {
'dob' => '23 June 2006',
'price' => '25'
},
'Madness' => {
'dob' => '1 February 2004',
'price' => '150'
}
},
'dog' => {
'owner' => 'Rosie',
'dob' => '12 October 2005',
'name' => 'Maggie',
'price' => '75'
}
};
���������ʧ��ġ�è���ı�ʾ��ʽ��ȫ��һ����ֻè����Ϣ�洢��һ��˫��Ƕ��ɢ���У��������Ϊ�����ڹ�����Ϣ�洢��һ����ɢ���У�������ֻ������֮һ�����⣬��Ԫ�ص������ʧ�ˡ�������ȥ�Ķ��ĵ����μ� �ο����ϣ���������һЩѡ������� ForceArray=>1 �� KeepRoot=>1����һ��ѡ��ʹ����Ƕ��Ԫ�ض���ʾΪ���顣�������еڶ���ѡ��ָʾ������Ԫ�ص���ơ������ں��������п����ģ�����ζ����ݵ��ڴ��ʾ����Ԫ�ص���ơ�ʹ����Щѡ��֮�õ����嵥 9 �еĽ������ڳ���Ա��˵�������������ˣ�������ռ�õ��ڴ�Ҫ��һ���
�嵥 9. ���ѡ��֮��� Data::Dumper ����������Щ���ɶ����������
$VAR1 = {
'pets' => [
{
'cat' => [
{
'dob' => [ '1 February 2004' ],
'name' => [ 'Madness' ],
'price' => [ '150' ]
},
{
'dob' => [ '23 June 2006' ],
'name' => [ 'Little' ],
'price' => [ '25' ]
}
],
'dog' => [
{
'owner' => [ 'Rosie' ],
'dob' => [ '12 October 2005' ],
'name' => [ 'Maggie' ],
'price' => [ '75' ]
}
]
}
]
};
���ڴ��е���ݽṹ����ת��
�������ڴ����Ѿ�����һ������Ľṹ���dz�����ͨ���������Ϊ��ʵ�����ϰ�ĵ�һ��Ҫ����Ԫ��ת��Ϊ���ԣ�����Ҫ�滻����������ã����嵥 10 ��ʾ��
�嵥 10. �Ե�Ԫ�����������
'name' => [ 'Maggie' ]
Ȼ�����滻��ֵ�����ã����嵥 11 ��ʾ��
�嵥 11. ��ֵ������
'name' => 'Maggie'
������һ�ģ�XML::Simple �����һ������ ���� ֵ�ԣ�������Ԫ�ء�����Ҫ���һ�����͵Ķ��ʵ�������� ���� �����ʾ���У�����ֻè��һֻ�� ���� ��Ҫ������ɢ�е������������ʽ�ռ�ɢ�С��嵥 12 ��ʾ����������е�����Ե�����
�嵥 12. ������ת��Ϊɢ�У��Ӷ�Ԫ��ת��Ϊ����
sub makeNewHash($) {
my $hashRef = shift;
my %oldHash = %$hashRef;
my %newHash = ();
while ( my ($key, $innerRef) = each %oldHash ) {
$newHash[$key] = @$innerRef[0];
}
return \%newHash;
}
���һ��������������� XML ���ã���δ��뽫��ת��Ϊһ��ɢ�С���������ֻ��һֻ�����ô����Ϳ����ˡ����Խ������ɢ�е�����д�� $data�����ǣ����������ж�ֻ���Ҫд�صľ�Ӧ���Ƕ�һ��������������ã���������������������������ɢ�е����á����Բ鿴�������������嵥 16���е� foldType()���˽��������ʵ�ֵġ�
��������Perl �ij�ɫ֮��
�ϰ�����������Ƕ��б���������۸���� 20%�����۸�д����λС���Լ��������滻�������ڡ���һ���������账�?��Ϊ���� XML::Simple �����Ĭ�����á��� Perl �У��ڶ����͵��������ֻ��һ�д�����ܹ�ʵ�֡�Perl ���кܷ���Ķ�̬�ԣ��ڽ��۸���� 20% ʱ���۸������֣����ǣ����������Ϊ�ַ�д�أ����ǻᱣ������ָ���ĸ�ʽ�������嵥 13 ͬʱ���������������ַ�ת��Ϊ���֣��������ת�����ַ�
�嵥 13. ��۸����¸�ʽ��
sprintf "%6.2f", $amt * (1 + $change)
����������ת��Ϊ�����е�����ѡ����ǣ��о�һ�� CPAN �ͻᷢ�֣�Date::Calc �ṩ��������������ԣ���������������ԣ���Decode_Date_EU �� ��European�� ��ʽ�����ڣ����� 13 January 2006��ת��Ϊ���Ԫ�ص����飨YMD�������������ʹ�õı����ڸ�ʽ�����������������ڣ�Delta_YMD($earlier, $later) �������ͬ��ʽ��ʱ������Ϳ��Եõ����䡣�������ǣ�Delta_YMD �е�������ʱ������·ݻ��Ǹ����ǣ��� google �Ϻ��������������������������������� �嵥 16���е� deltaYMD ��ʾ����δ���������⡣
��è�����з���
Ϊ��ʹ�����������չ��Ҫʹ���嵥 14 ��ʾ�ķ��ɱ?Jason Dominus �ľ������� Higher Order Perl ����ϸ�����˷��ɱ?�μ� �ο����� �е����ӣ���
�嵥 14. ���ɱ�
my $DISPATCHER = {
'cat' => sub { foldType(shift); },
'dog' => sub { foldType(shift); },
'hippo' => \&hippoFunc,
};
���ɱ�������������ض�Ԫ�ص�ʵ�ʴ��루��������̣���Ҳ����Ա������������̵����á�����ʹ�����ֽṹʵ������������ switch-case �ṹ��Ч��
�����ʾ���У�ֻ������Ԫ�����ͣ�è��������ʵ�� XML �ĵ��У����������Ԫ�����ͣ����Ҵ��ڲ�ͬ�IJ���ϡ����ܿ����� Perl ��ʹ�� if ... elsif ... elsif �ṹ������ʹ��һ���������ɱ�Ҫ����ö࣬���Ҹ�����ά����
�� XML д�ش���
XML::Simple ��Ĭ�����ͨ���Ǻܺ���ġ����û��Ϊ XMLout() ָ��ѡ���ͻ����һ���ַ����ϣ�����д���ļ��У���Ҫ���� OutputFile ѡ����û������ָ���Ļ�����ʹ�� ��Ϊ��Ԫ�ء�����ڴ��е���ݽṹ���и�Ԫ����ƣ���ô��� KeepRoot ѡ������ѡ������Ϊ true ���� 1���� Perl �� 1 ��ʾ�棩���嵥 15 ��ʾ�˾���������
�嵥 15. ����� XML �ļ�
$simple->XMLout($data,
KeepRoot => 1,
OutputFile => 'pets.fixed.xml',
XMLDecl => "<?xml version='1.0'?>",
);
����Ľ������
�嵥 16 �е� 112 �д���Ϳ�������ϰ��Ҫ��XML::Simple �ļ����ȷʵ����ӡ����̡��� 8 �д���������д XML����������һС�������ת�� XML �Ľṹ��
�嵥 16. ��������հ汾
#!/usr/bin/perl -w
use strict;
use XML::Simple;
use Date::Calc qw(Add_Delta_YM Decode_Date_EU Delta_Days Delta_YMD);
use Data::Dumper;
my $simple = XML::Simple->new (ForceArray => 1, KeepRoot => 1);
my $data = $simple->XMLin('pets.xml');
my @now = (localtime(time))[5, 4, 3];
$now[0] += 1900; # Perl years start in 1900
$now[1]++; # months are zero-based
sub fixPrice($$) {
my ($amt, $change) = @_;
return sprintf "%6.2f", $amt * (1 + $change);
}
sub deltaYMD($$) {
my ($earlier, $later) = @_; # refs to YMD arrays
my @delta = Delta_YMD (@$earlier, @$later);
while ( $delta[1] < 0 or $delta[2] < 0 ) {
if ( $delta[1] < 0 ) { # negative month
$delta[0]--;
$delta[1] += 12;
}
if ( $delta[2] < 0 ) { # negative day
$delta[1]--;
$delta[2] = Delta_Days(
Add_Delta_YM (@$earlier, @delta[0,1]), @$later);
}
}
return \@delta;
}
sub dob2age($) {
my $strDOB = shift;
my @dob = Decode_Date_EU($strDOB);
my $ageRef = deltaYMD( \@dob, \@now );
my ($ageYears, $ageMonths, $ageDays) = @$ageRef;
my $age;
if ( $ageYears > 1 ) {
$age = "$ageYears years";
} elsif ($ageYears == 1) {
$age = '1 year' . ( $ageMonths > 0 ?
( ", $ageMonths month" . ($ageMonths > 1 ? 's' : '') )
: '');
} elsif ($ageMonths > 1) {
$age = "$ageMonths months";
} elsif ($ageMonths == 1) {
$age = '1 month' . ( $ageDays > 0 ?
( ", $ageDays day" . ($ageDays > 1 ? 's' : '') ) : '');
} else {
$age = "$ageDays day" . ($ageDays != 1 ? 's' : '');
}
return $age;
}
sub makeNewHash($) {
my $hashRef = shift;
my %oldHash = %$hashRef;
my %newHash = ();
while ( my ($key, $innerRef) = each %oldHash ) {
my $value = @$innerRef[0];
if ($key eq 'dob') {
$newHash{'age'} = dob2age($value);
} else {
if ($key eq 'price') {
$value = fixPrice($value, 0.20);
}
$newHash{$key} = $value;
}
}
return \%newHash;
}
sub foldType ($) {
my $arrayRef = shift;
# if single element in array, return simple hash
if (@$arrayRef == 1) {
return makeNewHash(@$arrayRef[0]);
}
# if multiple elements, return array of simple hashes
else {
my @outArray = ();
foreach my $hashRef (@$arrayRef) {
push @outArray, makeNewHash($hashRef);
}
return \@outArray;
}
}
my $dispatcher = {
'cat' => sub { foldType(shift); },
'dog' => sub { foldType(shift); },
};
my @base = @{$data->{pets}};
my %types = %{$base[0]};
my %newTypes = ();
while ( my ($petType, $arrayRef) = each %types ) {
my @petArray = @$arrayRef;
print "type $petType has " . @petArray . " representatives \n";
my $refReturned = &{$dispatcher->{$petType}}( $arrayRef );
$newTypes{$petType} = $refReturned;
}
$data->{pets} = \%newTypes; # overwrite existing data
$simple->XMLout($data,
KeepRoot => 1,
OutputFile => 'pets.fixed.xml',
XMLDecl => "<?xml version='1.0'?>",
);
���ܻ�������� Perl ������࣬�������Ѿ�����˵���� Perl �д��� XML �Ƕ�ô���ס������ǣ�ͨ��ʹ�÷��ɱ?�����շdz������ҿ�ά���ķ�ʽ������ͬ�ṹ��Ԫ�����͡�
����
���ҵ��ǣ���Щ�������� XML::Simple ��ɡ��ҽ��ڵ� 2 ���ֺ͵� 3 ��������ϸ����������⣬���� XML::Simple ��������Ҫ���ơ����ȣ������뷽�棬������� XML �ļ������ڴ棬��������ļ��dz��������Ҫ���� XML ��������Ͳ���ʹ�����ģ�顣�ڶ����������� XML ������ݣ�Ҳ������һ��Ԫ������ͬʱ�����ı�����Ԫ�ص���������嵥 17 ��ʾ��
�嵥 17. �������
<example>of <mixed/> content</example>
����ж��ļ��Ƿ�̫���ˣ�XML::Simple ���?�ˣ���������ǣ�XML �������ڴ�ʱ������� 10 ��������ζ�ţ������Ĺ���վ���м��� MB �Ŀ����ڴ棬��ô XML::Simple �ܹ������ XML �ļ���С���Ϊ��ʮ MB��
������
XML �ڼ��㻷�����Ѿ��������ˣ�����Խ��Խ���ֲ�����ִ�Ӧ�ó���Ͳ���ϵͳ�С�Perl ����Ա������Ҫ����ʹ�� XML �ķ�����XML::Simple ����Ĺ����ܹ����ɵؽ� XML �ĵ�ת��Ϊ�������� Perl ��ݽṹ���Լ�����Щ��ݽṹת���� XML����Щ����һ��ֻ��һ�д��롣
��һ���棬XML ר��Ҳ�ᾪϲ�ط��� Perl ��ת������Ӧ XML ���ݷ����Ƕ�ô�а���
�� 2 ���ֽ���������� Perl �н���������Ҫ�� XML ���������������¼���Ľ�����
-----------------------------------------------------------------------
ת�ԣ�http://tilt.lib.tsinghua.edu.cn/node/561
--
[1;36mHappy XMLing
[m[1;35m�� ��Դ:��ˮľ���� newsmth.net��[FROM: 114.249.210.*][m
Technical Details
Message-ID:
<4lX9EZ$CLp@newsmth.net>Path:
arc1-ca.pugleaf.net!g2news2.google.com!news1.google.com!npeer03.iad.highwinds-media.com!news.highwinds-media.com!feed-me.highwinds-media.com!nx02.iad01.newshosting.com!209.197.12.242.MISMATCH!nx01.iad01.newshosting.com!newshosting.com!198.186.194.249.MISMATCH!transit3.readnews.com!news-xxxfer.readnews.com!news-out.readnews.com!transit4.readnews.com!teleglobe.net!newsgate.cuhk.edu.hk!news.neu.edu.cn!news.newsmth.net!NEWSMTHShow Full Headers
Complete Article Headers
X-Google-Thread: 115571,fa06877fbd4f2730,start X-Google-NewGroupId: yes X-Google-Attributes: gidf7ebf7e2af,domainid0,public,usenet X-Google-Language: Chinese,GB Path: arc1-ca.pugleaf.net!g2news2.google.com!news1.google.com!npeer03.iad.highwinds-media.com!news.highwinds-media.com!feed-me.highwinds-media.com!nx02.iad01.newshosting.com!209.197.12.242.MISMATCH!nx01.iad01.newshosting.com!newshosting.com!198.186.194.249.MISMATCH!transit3.readnews.com!news-xxxfer.readnews.com!news-out.readnews.com!transit4.readnews.com!teleglobe.net!newsgate.cuhk.edu.hk!news.neu.edu.cn!news.newsmth.net!NEWSMTH From: thinkhy@newsmth.net-SPAM.no (<Test/>) Newsgroups: cn.bbs.comp.xml Subject: ���� Perl ������Ա�� XML���� 1 ����(ת��) Date: 27 Apr 2010 15:34:04 GMT Organization: ˮľ���� Message-ID: <4lX9EZ$CLp@newsmth.net> Mime-Version: 1.0 Content-Type: text/plain; charset="gb2312" Content-Transfer-Encoding: 8bit X-Filename: XML/f/M.1272382403.80