我一直在互联网上搜索2天,试图找到如何使用Perl XML Parsers正确引用多级XML文件的答案。我是Perl的新手,这是我在这个论坛的第一篇文章,所以我有很多东西需要学习。我从XML :: Simple开始。我意识到有些人对其他图书馆有偏好。
XML示例文件:
<events>
<event>
<EventObject>Application</EventObject>
<EventType>Start</EventType>
<Operation></Operation>
<EventTimestamp>Sat 11/21/2015-14:02:57.76</EventTimestamp>
</event>
<source>
<UserIPAddr>192.168.1.2</UserIPAddr>
<UserHostName>ABC-PROD-BAR-15-01A</UserHostName>
<UserUUID>EC2-User</UserUUID>
</source>
<target>
<URL>"https://foo.com/"</URL>
</target>
<payload>
<FormData></FormData>
<PackageFilename></PackageFilename>
</payload>
<event>
<EventObject>User</EventObject>
<EventType>Download</EventType>
<Operation>Acknowledge License</Operation>
<EventTimestamp>Sat 11/21/2015-14:03:10.44</EventTimestamp>
</event>
<source>
<UserIPAddr>10.120.30.4</UserIPAddr>
<UserHostName>WSM24CN502</UserHostName>
<UserUUID>simpson homer 750329 </UserUUID>
</source>
<target>
<URL>"https://dev.catalog.com/"</URL>
</target>
<payload>
<FormData></FormData>
<PackageFilename>"eclipse.luna.5.2.tag.gz"</PackageFilename>
</payload>
</events>
示例代码:
#!perl
# use module
use XML::Simple;
use Data::Dumper;
use XML::Parser;
# create object
$xml = new XML::Simple (KeyAttr=>[]);
# read XML file
my $data = $xml->XMLin("auditfile3.xml",forcearray=>1);
#$data = $xml->XMLin("auditfile3.xml",KeyAttr=>{EventRecord=>'Event'});
print Dumper($data);
#print $data->{Events}->{Event};
#my $EventRecord = $data->{EventRecord};
#print Dumper($EventRecord);
#print $EventRecord->{EventObject};
#print $data->{EventObject};
# dereference hash ref
# access <EventRecord> array
foreach my $e (@{$data->{Event}})
{
print "EventObject: ",$e->{Event->{EventObject}}, "\n";
print "EventType: ", $e->{EventType}, "\n";
print "Operation: ", $e->{Operation}, "\n";
print "Timestamp: ", $e->{EventTimestamp}, "\n";
}
答案 0 :(得分:2)
#!/usr/bin/env perl
use strict;
use warnings;
use feature qw(say);
use XML::LibXML;
my $xml = XML::LibXML->load_xml( IO => \*DATA );
for my $node ( $xml->findnodes('//event') ) {
for my $property (qw(EventObject EventType Operation EventTimestamp)) {
next unless my ($child) = $node->findnodes($property);
say "$property: ", $child->textContent();
}
say '';
}
__DATA__
<events>
<event>
<EventObject>Application</EventObject>
<EventType>Start</EventType>
<Operation></Operation>
<EventTimestamp>Sat 11/21/2015-14:02:57.76</EventTimestamp>
</event>
<source>
<UserIPAddr>192.168.1.2</UserIPAddr>
<UserHostName>ABC-PROD-BAR-15-01A</UserHostName>
<UserUUID>EC2-User</UserUUID>
</source>
<target>
<URL>"https://foo.com/"</URL>
</target>
<payload>
<FormData></FormData>
<PackageFilename></PackageFilename>
</payload>
<event>
<EventObject>User</EventObject>
<EventType>Download</EventType>
<Operation>Acknowledge License</Operation>
<EventTimestamp>Sat 11/21/2015-14:03:10.44</EventTimestamp>
</event>
<source>
<UserIPAddr>10.120.30.4</UserIPAddr>
<UserHostName>WSM24CN502</UserHostName>
<UserUUID>simpson homer 750329 </UserUUID>
</source>
<target>
<URL>"https://dev.catalog.com/"</URL>
</target>
<payload>
<FormData></FormData>
<PackageFilename>"eclipse.luna.5.2.tag.gz"</PackageFilename>
</payload>
</events>
输出:
EventObject: Application
EventType: Start
Operation:
EventTimestamp: Sat 11/21/2015-14:02:57.76
EventObject: User
EventType: Download
Operation: Acknowledge License
EventTimestamp: Sat 11/21/2015-14:03:10.44
答案 1 :(得分:0)
XML元素名称区分大小写。此外,代码中存在一些语法错误。
my $xml = 'XML::Simple'->new(KeyAttr => [], ForceArray => 1);
my $data = $xml->XMLin(...);
for my $e (@{ $data->{event} }) {
print "EventObject: ", $e->{EventObject}[0], "\n";
print "EventType: ", $e->{EventType}[0], "\n";
print "Operation: ", ref $e->{Operation}[0] ? '-empty-'
: $e->{Operation}[0], "\n";
print "Timestamp: ", $e->{EventTimestamp}[0], "\n";
}