-6

So I have a simple hash key=>{value} and I need to output this in an XML file (in a specific location).

The output should be like this:

<keys> <key1> <value1> </value1> </key1> </keys> 

I searched on other forums and found that xml::Simple would be a solution, but new in Perl.

Sobrique
  • 52,974
  • 7
  • 60
  • 101
user30771
  • 109
  • 6

2 Answers2

2

XML::Simple is abysmal, especially for generating XML.


You said the format should be the following:

<keys>
   <key1><value1></value1></key1>
   [...]
</keys>

That format doesn't make much sense. The solution below produces XML in the following format:

<elements>
   <element><key>key1</key><value>value1</value></element>
   [...]
</elements>

Solution:

use XML::Writer qw( );

open(my $fh, '>', $qfn)
   or die("Can't create \"$qfn\": $!\n");

my $writer = XML::Writer->new(OUTPUT => $fh);
$writer->xmlDecl();
$writer->startTag("elements");
for my $key (sort keys(%hash)) {
   $writer->startTag("element");
   $writer->dataElement("key", $key);
   $writer->dataElement("value", $hash{$key});
   $writer->endTag("element");
}
$writer->endTag("keys");
$writer->end();

The following is a terser format:

<elements>
   <element key="key1">value1</element>
   [...]
</elements>

Solution:

use XML::Writer qw( );

open(my $fh, '>', $qfn)
   or die("Can't create \"$qfn\": $!\n");

my $writer = XML::Writer->new(OUTPUT => $fh);
$writer->xmlDecl();
$writer->startTag("elements");
for my $key (sort keys(%hash)) {
   $writer->dataElement("element", $hash{$key}, key => $key);
}
$writer->endTag("keys");
$writer->end();

Adjust at will.

ikegami
  • 367,544
  • 15
  • 269
  • 518
0

ikegami has covered the hash -> XML case quite nicely. I wish to offer an alternative suggestion - don't, use JSON instead. XML is quite powerful and complicated, but it's really designed as a document format - think how HTML does things - you have tags, attributes and content.

For a significant number of use cases, you're better off with JSON instead - it's a simpler format of hashes and arrays. As a result, it more directly reflects the perl data types.

So you can do:

#!/usr/bin/env perl

use strict;
use warnings;

use JSON;

my %stuff = ( key => "value", 
              another_key => "another_value", 
              some_tags => [ "tag1", "tag2", "tag3" ] ); 

print to_json ( \%stuff, { pretty => 1 } );

This gives you:

{
   "key" : "value",
   "another_key" : "another_value",
   "some_tags" : [
      "tag1",
      "tag2",
      "tag3"
   ]
}

Or collapses it onto one line if you just to_json ( \%stuff );:

{"another_key":"another_value","key":"value","some_tags":["tag1","tag2","tag3"]}

Reading it back in is as simple as:

my $json_str =  to_json ( \%stuff );

my $json_object = from_json ( $json_str );
print Dumper \$json_object;

If all you need is hashes and arrays (and can do without XML attributes, xpath, XSLT processing) then this may be a better fit - I suggest it, because you indicate that you want to export a simple hash.

But in either case - don't use XML::Simple - it isn't simple at all.

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