tags:

views:

1245

answers:

7

Hello

I need to create XML in Perl. From what I read, XML::LibXML is great for parsing and using XML that comes from somewhere else. Does anyone have any suggestions for an XML Writer? Is XML::Writer still maintained? Does anyone like/use it?

In addition to feature-completeness, I am interested an easy-to-use syntax, so please describe the syntax and any other reasons why you like that module in your answer.

Please respond with one suggestion per answer, and if someone has already answered with your favorite, please vote that answer up. Hopefully it will be easy to see what is most popular.

Thanks!

+8  A: 

XML::Writer is still maintained (at least, as of February of this year), and it's indeed one of the favorite Perl XML writers out there.

As for describing the syntax, one is better to look at the module's documentation (the link is already in the question). To wit:

 use XML::Writer;

  my $writer = new XML::Writer();  # will write to stdout
  $writer->startTag("greeting", 
                    "class" => "simple");
  $writer->characters("Hello, world!");
  $writer->endTag("greeting");
  $writer->end();
  $output->close();

  # produces <greeting class='simple'>Hello world!</greeting>
Yanick
Thanks, I did look at the documentation for XML::Writer. I was hoping for a somewhat cleaner syntax, so I will wait a bit to see if anyone else chimes in with any suggestions, but if this seems to be the favorite, than I will go with it.
pkaeding
Syntax "maybe" long in the tooth but XML::Writer as served me well for over 8 years now. Its the one I reach for first when needing to create XML from Perl. For something more "sexier" then check out XML::Class (however note this hasn't been updated since 2005).
draegtun
Re. "cleaner syntax", the "greeting" tag in the example above could have been written: $writer->dataElement("greeting", "Hello, world!", "class"=>"simple"). I don't see how much simpler this could be.
R. Hill
XML::Writer is maintained - that's what I use too. Unfortunately, it could still be better. As far as I know it doesn't perform self-enclosing tags. Plus, there's no way to add attributes after the tag has been written (it's not really object based).
vol7ron
+4  A: 

I don't do much XML, but XML::Smart looks like it might do what you want. Take a look at the section Creating XML Data in the doc and it looks very simple and easy to use.

Paraphrasing the doc:

use XML::Smart;

## Create a null XML object:
my $XML = XML::Smart->new() ;

## Add a server to the list:
$XML->{server} = {
    os => 'Linux' ,
    type => 'mandrake' ,
    version => 8.9 ,
    address => '192.168.3.201' ,
} ;

$XML->save('newfile.xml') ;

Which would put this in newfile.xml:

<server os="Linux" type="mandrake" version="8.9">
  <address>192.168.3.201</address>
  <address>192.168.3.202</address>
</server>

Cool. I'm going to have to play with this :)

Matt Siegman
+3  A: 

XML::Smart looks nice, but I don't remember it being available when I was using XML::Simple many years ago. Nice interface, and works well for reading and writing XML.

Bill Turner
+5  A: 

If you want to take a data structure in Perl and turn it into XML, XML::Simple will do the job nicely.

At its simplest:

my $hashref = { foo => 'bar', baz => [ 1, 2, 3 ] };
use XML::Simple;
my $xml = XML::Simple::XMLout($hashref);

As its name suggests, its basic usage is simple; however it does offer a lot of features if you need them.

Naturally, it can also parse XML easily.

David Precious
+1  A: 

I like XML::TreeBuilder because it fits the way I think. Historically, I've used it more for parsing than emitting.

A few weeks after this question was posted, I had occasion to generate some XML from Perl. I surveyed the other modules listed here, assuming one of them would work better than XML::TreeBuilder, but TreeBuilder was still the best choice for what I wanted.

One drawback was there is no way to represent processing instructions and declarations in an XML::TreeBuilder object.

skiphoppy
I agree with you Brian.In my case, I decided to give XML::LibXML a try also for writing because the piece of code I was changing was already using XML::LibXML for other tasks.
cosimo
Brian's just the editor who added the link; I'm the one who made the comment. :)
skiphoppy
+2  A: 

Just for the record, here's a snippet that uses XML::LibXML.

#!/usr/bin/env perl

#
# Create a simple XML document
#

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

my $doc = XML::LibXML::Document->new('1.0', 'utf-8');

my $root = $doc->createElement("my-root-element");
$root->setAttribute('some-attr'=> 'some-value');

my %tags = (
    color => 'blue',
    metal => 'steel',
);

for my $name (keys %tags) {
    my $tag = $doc->createElement($name);
    my $value = $tags{$name};
    $tag->appendTextNode($value);
    $root->appendChild($tag);
}

$doc->setDocumentElement($root);
print $doc->toString();

and this outputs:

<?xml version="1.0" encoding="utf-8"?>
<my-root-element some-attr="some-value">
    <color>blue</color>
    <metal>steel</metal>
</my-root-element>
cosimo
A: 

Any suggestion about which would be best for generating extremely large ( > 1GB ) XML files? I have a script that I inherited that currently uses XML::Writer, but it takes a very long time to compile a 1.6GB XML file (i.e., more than 15 minutes). Usually, these file are about half that size, but at times they can be 1GB large.

It almost makes me think I'd be better off just using perl's file handling, and simply wrap the content with string tag and append the file without an XML class handler. The script is really only using it for basic tag wrapping. There's not much hierarchical XML in this output.

I'm trying to find a less-resource-intensive way to spit out a simple XML tree to the file.

Thoughts? Thanks!

Greg Stewart