CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Intermediate:
Using XML file within PERL

 



bradleyb
New User

Mar 10, 2009, 5:19 PM

Post #1 of 2 (852 views)
Using XML file within PERL Can't Post

I have an XML file that I've read into a perl script using XML::Simple and would like to know how to reference the data included in the file within the program.

Something similar to this:

use XML::Simple;
$data = $xml->XMLin("c:\\users\\brad\\desktop\\1.139.sysinfo.xml");
print $data->{'operating system'}->{software}->{Security};

That's all I need to know how to do and might be as simply as me not knowing the starting or ending point in the above print statement with the variable names.
Attachments: 1.139.sysinfo.zip (3.67 KB)


1arryb
User

Mar 11, 2009, 8:17 AM

Post #2 of 2 (845 views)
Re: [bradleyb] Using XML file within PERL [In reply to] Can't Post

Hi bradley,

1. <operating system> isn't a valid xml tag (no spaces allowed). Such a tag will never parse.

2. Use one of the data dumpers out there to see what the parsed structure looks like. I recommend Dumpvalue:

Code
Use Dumpvalue; 
...
my $dumper = Dumpvalue->new(dumpReused => 1);
$dumper->dumpValue($data);
...


3. Read the XML::Simple perldoc. This module has a ton of options and the default values don't return a useful result:

3.1 You almost always want to initialize the parser as 'XML::Simple->new(ForceArray => 1). Otherwise, the structure of the parse result is indeterminant (unique tags are returned as hashes while repeating tags are returned as arrays, yuck!).

3.2 By default, the outermost tag is stripped out of the parse result. Initialize the parser with KeepRoot => 1 to prevent this.

3.3 By default, any text is returned unaltered by the parser. To have XML::Simple strip out leading, trailing spaces and newlines from text strings, initialize the parser with NormalizeWhitespace => 2.

4. Putting it together.

Assuming your xml file looks like:

Code
<?xml version='1.0' encoding='UTF-8'?> 
<operatingsystem>
<software>
<Security>
My security data
</Security>
</software>
</operatingsystem>


You could parse it like this:

Code
#!/usr/bin/perl 

use strict;
use warnings;
use XML::Simple;
use Dumpvalue;

my $file = $ARGV[0];
die "usage: $0 <xmlfile>" unless $file;

my $xs = XML::Simple->new(ForceArray => 1, KeepRoot => 1, NormalizeSpace => 2);
my $data = $xs->XMLin($file);
my $dumper = Dumpvalue->new(dumpreused => 1);
$dumper->dumpValue($data);


If you run the program, it outputs:

Code
'operatingsystem' => ARRAY(0x16bded0) 
0 HASH(0x1252d00)
'software' => ARRAY(0x16bdf00)
0 HASH(0x1252e70)
'Security' => ARRAY(0x10ff740)
0 'My security data'

To get to the value of your 'Security' tag:

Code
    ... 
my $security = $data->{operatingsystem}->[0]->{software}->[0]->{Security};
...


Note that the name of each tag is a key in the enclosing hash. The value of each tag is an array. This can lead to seemingly redundant layers in the parse, but it's the only way to guarantee a regular result structure that you can traverse in a script.

UPDATE

Well, not the only way (this is Perl, after all). You could omit ForceArray => 1 and check the type of each level in the parse (e.g., if ( ref($element) eq 'HASH' ) ...). That's not my style, but YMMV.

Hope this helps.

Cheers,

Larry


(This post was edited by 1arryb on Mar 11, 2009, 8:21 AM)

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives