Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Re: Module for XML output

by ambrus (Abbot)
on Jan 11, 2012 at 14:08 UTC ( [id://947349]=note: print w/replies, xml ) Need Help??


in reply to Module for XML output

You can use XML::Twig to create new XML files. There's not many example for this around, probably because XML::LibXML is for those who believe in XML, and XML::Twig is for those who don't but have to work with it, and obviously it's more frequently the former who want to create new XML. (Update 2011-01-13: on the other hand, code for building XML from scratch with XML::LibXML can look a bit ugly, because XML::LibXML is a straight wrapper over the C library, so it won't give you methods that accept a variable number and type of arguments like the constructors I'm using below.)

Anyway, there are two styles you can use to create new XML with Twig (though you can mix them). Here.

use warnings; use strict; use XML::Twig; { # from the inside my $para1text1 = "There are two ways to build XML with "; my $moduletext = "Twig"; my $module = XML::Twig::Elt->new("a", {"href" => "http://mirod +.org/"}, $moduletext); my $para1text2 = ": "; my $para1 = XML::Twig::Elt->new("p", $para1text1, $module, $p +ara1text2); my $para2text = "from the inside and from outside."; my $para2 = XML::Twig::Elt->new("p", $para2text); my $root = XML::Twig::Elt->new("saying", $para1, $para2); my $twig = XML::Twig->new(pretty_print => "nice"); $twig->se +t_root($root); $twig->flush(*STDOUT); } { # from the outside my $twig = XML::Twig->new(pretty_print => "nice"); my $root = XML::Twig::Elt->new("saying"); $twig->set_root($root); my $para1 = $root->insert_new_elt(last_child => "p"); $para1->suffix("There are two ways to build XML with "); my $module = $para1->insert_new_elt(last_child => "a", {"href" => "http://mirod.org/"}); # or this would work too: #$module = $para1->insert_new_elt(last_child => "a"); #$module->set_att("href" => "http://mirod.org/"); $module->suffix("Twig"); $para1->suffix(": "); my $para2 = $root->insert_new_elt(last_child => "p"); $para2->suffix("from the inside and from outside."); $twig->flush(*STDOUT); }

If you don't wish to keep the whole XML structure in memory, you have to use the second method for at least the outer layers. After adding each larger chunk of the document (here after adding each paragraph), you call the flush method on that element which both outputs the XML document up to that part, and removes it from the document tree so it's no longer in the memory. Just don't forget to flush the twig at the very end so that the last closing tags are output. For example,

{ # from the outside, flushing after each paragraph my $twig = XML::Twig->new(pretty_print => "nice"); my $root = XML::Twig::Elt->new("saying"); $twig->set_root($root); my $para1 = $root->insert_new_elt(last_child => "p"); $para1->suffix("There are two ways to build XML with "); my $module = $para1->insert_new_elt(last_child => "a", {"href" => "http://mirod.org/"}); $module->suffix("Twig"); $para1->suffix(": "); $para1->flush(*STDOUT); my $para2 = $root->insert_new_elt(last_child => "p"); $para2->suffix("from the inside and from outside."); $para2->flush(*STDOUT); $twig->flush(*STDOUT); } { # combination, flusing after each paragraph my $twig = XML::Twig->new(pretty_print => "nice"); my $root = XML::Twig::Elt->new("saying"); $twig->set_root($root); my $para1text1 = "There are two ways to build XML with "; my $moduletext = "Twig"; my $module = XML::Twig::Elt->new("a", {"href" => "http://mirod +.org/"}, $moduletext); my $para1text2 = ": "; my $para1 = XML::Twig::Elt->new("p", $para1text1, $module, $p +ara1text2); $para1->paste($root); $para1->flush; my $para2text = "from the inside and from outside."; my $para2 = XML::Twig::Elt->new("p", $para2text); $para2->paste($root); $para2->flush; $twig->flush(*STDOUT); }

Update 2013-10-21: see the later question Best module for Creating [Writing out] XML.

Replies are listed 'Best First'.
Re^2: Module for XML output
by sundialsvc4 (Abbot) on Jan 11, 2012 at 15:50 UTC

    The hairiest, albeit perhaps most complete expression of a problem like this one .. appropriate perhaps only for fighting the biggest fires .. is to use a parser and to regard the XML output step as akin to creating an abstract-syntax tree (AST) in a true compiler-like situation.   Although the documentation for Parse::RecDescent was (to me, at least) rather baffling to read, it does specifically address this case.   I am frankly not suggesting it here, with regard to this post, but in those cases when you are dealing with a truly-nasty input file I can speak from personal experience that this approach does make a dramatically good result.   (I once used it to rip into a collection of about 6,000 fairly unpredictable SAS® files, korn-shell scripts, and Tivoli Workload Scheduler® scripts to construct a data-flow model of the entire system.   It was quite the beast to do, and there would have been no other way, I think, to have done it.)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://947349]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (5)
As of 2024-04-18 17:46 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found