2015-11-23 5 views
0

Я прочесываю интернет в течение 2 дней, пытаясь найти ответы на вопрос о том, как правильно ссылаться на многоуровневый файл XML, используя Perl XML Parsers. Я новичок в Perl, и это мой первый пост на этом форуме, поэтому мне нужно многому научиться. Я начинаю с XML :: Simple. Я понимаю, что у некоторых есть предпочтения для других библиотек. Файл SampleПонимание многоуровневой ссылки на XML с использованием Perl XML Parser?

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"; 
    } 
+3

Когда люди рекомендуют против использования XML :: Simple, это потому, что они пострадали боль, и они знают, что вызовет у вас боль. [Get off it] (http://www.perlmonks.org/index.pl?node_id=490846) скорее, чем позже :-) –

+0

[Почему XML: просто «обескуражен»] (http: // stackoverflow. com/questions/33267765/why-is-xmlsimple-disouraged) – Sobrique

ответ

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"; 
} 
+0

Спасибо, Чороба. Решение очень унизительно. – bbboomer

+0

Почему нужно ссылаться на массив [0]? И в чем разница между «for» и «foreach» в этом случае? Я думал, что между «foreach» и @, что он взял каждый элемент в массиве, созданном XMLin? – bbboomer

+0

@bbboomer: 'ForceArray' создает ссылки на массивы везде, поэтому вы должны использовать' [0] 'для получения своего первого элемента. 'for' и' foreach' - это одна и та же команда, но можно быстрее набирать 'for'. – choroba

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

Благодарим за отзыв и отличное решение. Поскольку проблема была решена, я никогда не искал дополнительных взносов. Очень признателен. – bbboomer

Смежные вопросы