-1

I'm trying to get the value of "longitude" from the following with XML::Simple.

Could anyone provide a code example?

<response>
<feedMessageResponse>
<count>1</count>
<feed>...
<id>02JvgufQqMhyMgAB5Rv7DOgge0LJjSly0</id>
</feed>
<totalCount>1</totalCount>
<activityCount>0</activityCount>
<messages>
<message clientUnixTime="0">
<id>527604536</id>
<messengerId>0-2136339</messengerId>
<messengerName>michael</messengerName>
<unixTime>1458736183</unixTime>
<messageType>TRACK</messageType>
<latitude>35.3825</latitude>
<longitude>-80.92035</longitude>
<modelId>SPOTCONNECT</modelId>
<showCustomMsg>N</showCustomMsg>
<dateTime>2016-03-23T12:29:43+0000</dateTime>
<messageDetail/>
<batteryState>GOOD</batteryState>
<hidden>0</hidden>
</message>
</messages>
</feedMessageResponse>
</response>
  • 1
    As the author of XML::Simple I heartily endorse XML::LibXML as a better choice - even for simple projects. In fact I wrote [Perl XML::LibXML by Example](http://grantm.github.io/perl-libxml-by-example/) specifically to help people make the move. – Grant McLean Mar 27 '16 at 19:42

3 Answers3

5

I wouldn't suggest using XML::Simple at all. It lies. It's not simple. See here: Why is XML::Simple "Discouraged"?

Instead:

#!/usr/bin/perl
use strict;
use warnings;

use XML::Twig;

print XML::Twig -> parse ( \*DATA) -> get_xpath('//longitude',0) -> text;

__DATA__
<response>
<feedMessageResponse>
<count>1</count>
<feed>...</feed>
<totalCount>1</totalCount>
<activityCount>0</activityCount>
<messages>
<message clientUnixTime="0">
<id>527604536</id>
<messengerId>0-2136339</messengerId>
<messengerName>michael</messengerName>
<unixTime>1458736183</unixTime>
<messageType>TRACK</messageType>
<latitude>35.3825</latitude>
<longitude>-80.92035</longitude>
<modelId>SPOTCONNECT</modelId>
<showCustomMsg>N</showCustomMsg>
<dateTime>2016-03-23T12:29:43+0000</dateTime>
<messageDetail/>
<batteryState>GOOD</batteryState>
<hidden>0</hidden>
</message>
</messages>
</feedMessageResponse>
</response>

Output:

-80.92035
Community
  • 1
  • 1
Sobrique
  • 52,974
  • 7
  • 60
  • 101
1

From the documentation for XML::Simple:

The use of this module in new code is discouraged. Other modules are available which provide more straightforward and consistent interfaces. In particular, XML::LibXML is highly recommended and XML::Twig is an excellent alternative.

The major problems with this module are the large number of options (some of which have unfortunate defaults) and the arbitrary ways in which these options interact - often producing unexpected results.

But if you want to ignore that warning, you can use XML::Simple like this:

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;

use XML::Simple;

my $doc = XMLin('data.xml');

say $doc->{feedMessageResponse}{messages}{message}{longitude};

Personally, I much prefer XML::LibXML.

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;

use XML::LibXML;

my $parser = XML::LibXML->new();
my $doc = $parser->parse_file('data.xml');

say $doc->findvalue('//longitude');
Dave Cross
  • 68,119
  • 3
  • 51
  • 97
1

I agree with Dave Cross, I find XML::LibXML to be a lot easier. This is what I would do if your file contained multiple longitude values

#!/usr/bin/perl

use warnings;
use strict;
use XML::LibXML;

my $file = 'test.xml'; #location of the file or it could be a url as well

my $parser = XML::LibXML->new();
my $tree = $parser->parse_file($file);
my $root = $tree->getDocumentElement;
my @longitude = $root->getElementsByTagName('longitude');

foreach my $res (@longitude) {
    print "Longitude : " . $res->textContent() . "\n";
}

This is just a simple example, you can change it to suit your needs

Ed Dunn
  • 1,152
  • 3
  • 11
  • 27