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

Re: Outputting a hash as XML

by Tanktalus (Canon)
on Mar 15, 2005 at 03:11 UTC ( [id://439533]=note: print w/replies, xml ) Need Help??


in reply to Outputting a hash as XML

XML::Twig is too flexible, and too verbose. But it's really quite cool once you get it working ... You didn't give your original hash structure, so I pretended what it was.

use strict; use XML::Twig; my $hash = { name => 'bob', value1 => 'blah', value2 => 'blah2', }; my $twig = XML::Twig->new(pretty_print => 'indented'); my $elt = create_element(newPhone => $hash); $twig->set_root($elt); $twig->print(); sub create_element { my $gi = shift; my $data = shift; my $t = XML::Twig::Elt->new($gi); if (ref $data) { while (my ($k,$v) = each(%$data)) { create_element($k, $v)->paste(last_child => $t); } } else { $t->set_text($data); } $t; }
Saved as "x":
$ perl x <newPhone> <value1>blah</value1> <name>bob</name> <value2>blah2</value2> </newPhone>
Hope that helps.

Replies are listed 'Best First'.
Re^2: Outputting a hash as XML
by mirod (Canon) on Mar 15, 2005 at 10:43 UTC
    XML::Twig is too flexible, and too verbose.

    Hey, did you try using the DOM? Now that would be what I'd call verbose!

    Seriously, if you have any idea about improvements, please send them my way, I'd be glad to include them (although I don't really understand the "too flexible" bit, I would think that flexible is a quality, see Perl...).

      I suppose I would put the XML::Twig::Elt docs into XML::Twig::Elt itself (or, if you have the code for XML::Twig::Elt inside XML/Twig.pm, put the pod into XML/Twig/Elt.pod). The docs are so long, it's hard to get one's head around it all. Maybe even an XML/Twig/Tutorial.pod would be nice (is there one and I'm not aware of it? If so - please put that in XML::Twig's pod! :->). The tutorial itself could just be a cookbook TOC - and there could be XML/Twig/Tutorial/NewTwig.pod (starting without any XML), XML/Twig/Tutorial/Load.pod (loading from string/file), XML/Twig/Tutorial/Handlers.pod, etc.

      Too flexible:

      $ perldoc XML::Twig | grep -i same.*as | wc -l 51
      You have a lot of options which duplicate each other. This simply helps obscure the unique options. I was trying to remember how to paste a twig inside another twig. Except that I didn't know it was called paste ;-). It took me probably 45-60 seconds of scanning the docs to find it. I found many ways to set the tag (gi, set_gi, tag, set_tag, ... did I miss any?), before getting paste. I also found (maybe this is just me) that paste was counterintuitive. I was expecting to tell the parent object what to insert, rather than telling the child object what its new parent is. So the first time I ran the above code, I had the create_element($k, $v) mixed up with the $t on the paste line. Of course, it didn't work. And, of course, you can't change this without breaking existing code.

      Don't get me wrong - XML::Twig is great. It has made me look good in my job (which is always important). And the fact that my successor on that project is creating XML by simply printing it out is, I'm sure, going to come back and bite him in the arse. (It's not quite the same physical project - just the same idea.) It just provides, in my experience, a significant learning curve. That said, when I chose to use it, I did look at as many of the XML parsers and handlers as I could on CPAN before choosing XML::Twig. And choose it I did. Because, as you sort of implied, it's the most perlish solution, IMO.

        Let's see what I can do:

        I suppose I would put the XML::Twig::Elt docs into XML::Twig::Elt

        See, I hate that. I have answered countless questions about XML::Parser with just a link to the docs for XML::Parser::Expat, because a lot of people don't realize that part of the doc is there. And I hate navigating the docs for basically all DOM modules, because the method I want to read about is always in an other class, hence in an other file. But I have an HTML version of the docs where you can expand/collapse levels, at http://xmltwig.com/xmltwig/twig_dev.html . It has some quirks, but it is what I use normally.

        Maybe even an XML/Twig/Tutorial.pod would be nice

        There is a tutorial at http://xmltwig.com/xmltwig/tutorial/index.html . It wasn't written in POD but rather in XML, with all the source code in separate files, so it might be difficult for me to create a POD from it (is there an HTM2POD converter somewhere?)

        I found many ways to set the tag (gi, set_gi, tag, set_tag, ... did I miss any?)

        Actually set_gi and set_tag are the only 2 ways, the other ones just return the tag. I apologize for this one. I am an SGML guy and tags were called gi's back in the days, but after being mocked for years by the young XML crowd I finally broke down and added tag and set_tag as aliases for gi and set_gi respectively. So yes, guilty here, but most of my code uses the gi form, so I am kinda reluctant to deprecate it ;--(

        You have a lot of options which duplicate each other. This simply helps obscure the unique options

        Agreed. There (of course!) reasons for a lot of those:

        • methods like tag/gi as already mentioned, where the domain vocabulary has changed in the lifetime of the module,
        • methods that are internally the same but represent different things for the users: first_child_text and field are synonyms, as are has_atts and att_nb, but I thought it made sense to express them differently,
        • methods that have a "Twig style" name but that also exist in the DOM or in HTML::Tree, like descendants and getElementsByTagName, and I agree this is probably overkill. Or at least I could document them separately,
        • finally, and once again I guess I have to take the blame, some aliases are quite whimsical, like sort_children_by_value and sort_children_on_value, which are both available because I couldn't decide which one I prefered

        In the end I guess all those aliases are a somewhat conscious design decision, to include everything and the kitchen sink in XML::Twig, to the point of indeed overwhelming users whith too many methods. It was also part of my master plan for for generating lucrative training gigs (no success there so far ;--(

        I also found (maybe this is just me) that paste was counterintuitive.

        You are not first one to think like this. I even added the, rather cryptic now that I read it again, The element is pasted sentence to the docs to warn users about it. I have now added a longer explanation. Note also that the method explecitely checks (and croaks) if the arguments appear to be reversed.

        Thank you for your comments. As mentioned I slightly tweaked the docs, and I moved the paragraph about additional resources to the very top of the POD, so hopefully users will have an easier time going through the learning curve. I think that's the best I can do right now. I have known that I will have to rethink the docs and try to come up with more material for the tutorial for quite a while, but I keep finding new things to code instead!

Re^2: Outputting a hash as XML
by Anonymous Monk on Aug 12, 2015 at 23:32 UTC
    I found the create_element function really useful, have added a slight modification to the above function to handle keys that are in turn array references
    sub create_element { my $gi = shift; my $data = shift; my $node = XML::Twig::Elt->new($gi); if (ref $data eq "HASH") { while (my ($key, $value) = each(%$data)) { if (ref $value eq "ARRAY") { for my $i (@$value) { createXmlTree($key, $i)->paste(last_child => $node); } } else { createXmlTree($key, $value)->paste(last_child => $node); } } } else { $node->set_text($data); } $node; };
    Thanks Joseph

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (7)
As of 2024-04-19 09:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found