使用Perl XML Parser了解多级XML引用?

时间:2015-11-23 01:07:42

标签: xml perl parsing multi-level

我一直在互联网上搜索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";
    }

2 个答案:

答案 0 :(得分:2)

使用XML::LibXML

#!/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";
}