문제

I'm trying to parse some XML into Perl, but testing isn't yielding what I'd expect.

$buffer = qq[<DeliveryReport><message id="msgID" sentdate="xxxxx" donedate="xxxxx" status="xxxxxx" gsmerror="0" /></DeliveryReport>];

$xml = XML::Simple->new( ForceArray => 1 );

$file = $xml->XMLin($buffer) or die "Failed for $reply: $!\n";
use Data::Dumper;
print Dumper($file);

$msgid          = $file->{message}->{id};
$message_status = $file->{message}->{status};
print "OUTPUT: $msgid  $message_status";

but the output is blank and the print Dumper looks wrong regards id attribute but I'm not sure why.

$VAR1 = {
    'message' => {
        'msgID' => {
            'status' => 'xxxxxx',
            'gsmerror' => '0',
            'sentdate' => 'xxxxx',
            'donedate' => 'xxxxx'
        }
    }
};

OUTPUT:

Here is the final code working correctly.

use XML::Simple;
use Data::Dumper;

$xml = XML::Simple->new (KeyAttr=>'',ForceArray => 1);
$file = $xml->XMLin('

<DeliveryReport>
    <message id="msgID1" sentdate="xxxxx" donedate="xxxxx" status="xxxxxx" gsmerror="0" />
    <message id="msgID2" sentdate="yyy" donedate="yyy" status="yyy" gsmerror="0" />
</DeliveryReport>
                ') or die "Failed for $reply: $!\n";

print Dumper($file);


$numOfMsgs = @{$file->{message}};
print "<br /><br />I've received $numOfMsgs records<br />";

for($i = 0; $i < $numOfMsgs; $i++) {

     $msgid = $file->{message}->[$i]->{id};
     $message_status = $file->{message}->[$i]->{status};

     print "message id: [$msgid]<br />";
     print "status id: [$message_status]<br />";
     print "<br />";
}
도움이 되었습니까?

해결책

By default, XML::Simple chooses to fold around the following keys by default: name, key, id (see note 1).

Your XML schema contains the id key, which is why the hash is being split there. You can clear the KeyAttr value when you create your object (e.g. $xml = XML::Simple( KeyAttr=>"" );) to override the default behavior.

Your output, with multiple message entries, would look like:

$VAR1 = {
          'message' => [
                       {
                         'gsmerror' => '0',
                         'status' => 'xxxxxx',
                         'id' => 'msgID',
                         'donedate' => 'xxxxx',
                         'sentdate' => 'xxxxx'
                       },
                       {
                         'gsmerror' => '1',
                         'status' => 'yyyyyy',
                         'id' => 'msgID2',
                         'donedate' => 'yyyyy',
                         'sentdate' => 'yyyyy'
                       }
                     ]
        };

So you need to adjust your code slightly to account for %message containing an array of message hashes. The format would be the same for a single message if you keep the ForceArray option, so your code change would work for both cases.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top