Subject: | Wishlist: start building a new XML without set_root |
Date: | Wed, 11 Jan 2012 15:31:52 +0100 |
To: | bug-XML-Twig [...] rt.cpan.org |
From: | Zsbán Ambrus <ambrus [...] math.bme.hu> |
After replying to a perlmonks question, I was again wondering on how
to build new XML documents from scratch with XML::Twig. In this
report, I'd like to brainstorm some ideas on how we could make this
easier.
So, in "http://www.perlmonks.com/?node_id=947349", I describe that
there are two different ways you can build a new XML document: from
the inside (preorder) or from the outside (postorder). Either of
these are supported by Twig, as are more complicated orders. Let's
look at this example code.
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,
$para1text2);
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->set_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/"});
$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);
}
IMO, the ugliest part of _both_ of these code is the set_root
function. It seems to me from the documentation that there's no way
to avoid the set_root function, despite that it does not really match
the style of _either_ of these two orders.
In the first case, when you're building the tree from the inside,
we're avoiding to call paste methods by passing the contents of each
element to the constructor call of that element. This works for all
elements but not for the twig itself. Wouldn't it be nicer if instead
of
my $twig = XML::Twig->new(pretty_print => "nice");
$twig->set_root($root);
we could just write
my $twig = XML::Twig->new(pretty_print => "nice", root => $root);
as a shortcut?
In the second case, when building the tree from the inside, we avoid
calling element constructors by calling the shortcut method
insert_new_elt. Again, this shortcut doesn't work for the twig
itself. Wouldn't it be nice if instead of
my $root = XML::Twig::Elt->new("saying"); $twig->set_root($root);
we could just write something like
$twig->insert_root_elt("saying");
as a shortcut (where this method would also accept an optional hashref
of attributes and a list of contents)? That would make the code more
uniform.
(Incidentally, is there a method to query the element class of a twig,
as set by the option elt_class? I think there should be, so that one
can implement a sub that takes a twig and behaves like the parse_html
method but parses something different. However, there does not seem
to be such a method documented.)
Finally, a minor point. Perhaps think XML::Twig::Elt should have an
insert_text method that behaves like the suffix method but takes a
position argument like insert_new_elt. That is,
$elt->insert_text($position, $text) would be like
$elt->insert_new_elt($position, "#PCDATA", $text) except that it tries
to combine the text with adjacent text elements.
Tell me what you think of all these. I don't promise to implement
anything, but it could happen.
Ambrus