Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Perl - Modify the nested XML tags

by Murari (Initiate)
on Jan 11, 2013 at 18:45 UTC ( #1012955=perlquestion: print w/ replies, xml ) Need Help??
Murari has asked for the wisdom of the Perl Monks concerning the following question:

I have a complex xml which I need to parse in PERL to output to different format input xml:
<?xml version="1.0" encoding="UTF-8"?> <response> <result name="response" numFound="58582" start="0"> <doc> <str name="body">Have a great time at this park!</str><int name="is_pa +rk_id">317851</int><str name="ss_image_thumb_small"/> <str name="title">Playground</str> </doc> <doc> <str name="body">Have a great time at this park!</str><int name="is_pa +rk_id">317851</int><str name="ss_image_thumb_small"/> <str name="title">Playground</str> </doc> </result> </response>
and the required output format is:
<?xml version="1.0" encoding="iso-8859-1"?> <Feed> <Products> <Product> <Description>Have a great time at this park!</Description><ExternalId> +PF317851</ExternalId><ImageUrl/> <Name>Playground</Name> </Product> <Product> <Description>Have a great time at this park!</Description><ExternalId> +PF317851</ExternalId><ImageUrl/> <Name>Playground</Name> </Product> </Products> </Feed>
<str name="body"> should be treated as description, <int name="is_park_id"> should be treated as <ExternalId> and <str name="title"> should be treated as <Name>. Could you help in formatting the XML to new format?

Comment on Perl - Modify the nested XML tags
Select or Download Code
Re: Perl - Modify the nested XML tags
by tobyink (Abbot) on Jan 11, 2013 at 21:05 UTC
    use strict; use warnings; use XML::LibXML 2; use XML::LibXML::PrettyPrint; my $xml = XML::LibXML::->load_xml(string => <<'INPUT'); <?xml version="1.0" encoding="UTF-8"?> <response> <result name="response" numFound="58582" start="0"> <doc> <str name="body">Have a great time at this park!</str> <int name="is_park_id">317851</int> <str name="ss_image_thumb_small"/> <str name="title">Playground</str> </doc> </result> </response> INPUT my %changes = ( '//response' => sub { $_->setNodeName('Fe +ed') }, '//result' => sub { $_->setNodeName('Pr +oducts'), %$_ = (); }, '//doc' => sub { $_->setNodeName('Pr +oduct'), %$_ = (); }, '//str[@name="body"]' => sub { $_->setNodeName('De +scription'), %$_ = (); }, '//int[@name="is_park_id"]' => sub { $_->setNodeName('Ex +ternalId'), %$_ = (); }, '//str[@name="ss_image_thumb_small"]' => sub { $_->setNodeName('Im +ageUrl'), %$_ = (); }, '//str[@name="title"]' => sub { $_->setNodeName('Na +me'), %$_ = (); }, ); while (my ($xpath, $processor) = each %changes) { $xml->findnodes($xpath)->foreach($processor); } print( XML::LibXML::PrettyPrint:: -> new(element => { compact => [qw/ Description ExternalId ImageUrl Name /], }) -> pretty_print($xml) -> toString );
    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
      I have the these libraries installed in my machine, couldn't use XML::LibXML. XML::NamespaceSupport, XML::Parser, XML::RegExp, XML::SAX, XML::Simple My requirement is multi-register document, could you help in the solution for the input nested XML?
Re: Perl - Modify the nested XML tags
by sundialsvc4 (Abbot) on Jan 11, 2013 at 22:26 UTC

    It may also be possible to express this using XSLT technology, entirely apart from Perl.   For an idea of what sort of things this technology can do, without programming, consider the interactive Periodic Table of the Elements example on the Internet.   (With your free hand, hold your lower jaw in place before you click on that link ...)   There is no programming being used to build the entire HTML of that display, and only a slight amount of JavaScript being used to respond to clicks and mouse-overs.   Your browser is the one doing all the work, on the fly, to produce what you see.   If your problem can be described as “fetch elements from an XML data source and make something else out of it,” this might be the cat’s meow.   A number of Perl libraries provide an industry standard XSLT capability, if it turns out that you need it.

      "without programming"

      Without any programming whatsoever... apart from over 4000 lines of Javascript, and an unspecified amount (it doesn't all seem to be publicly available, so I can't count the lines) of XSLT, which is itself a Turing-complete declarative programming language.

      perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: Perl - Modify the nested XML tags
by choroba (Abbot) on Jan 11, 2013 at 23:32 UTC
    There is how I would do it using XML::XSH2, a wrapper around XML::LibXML:
    open 1.xml ; rename Feed response ; cd Feed ; rename Products result ; cd Products ; rename Product doc ; cd Product ; rename Description str[@name="body"] ; rename ExternalId int[@name="is_park_id"] ; rename ImageUrl str[@name="ss_image_thumb_small"] ; rename Name str[@name="title"] ; insert text "PF" prepend ExternalId ; delete //*/@* ; save :b ;
    لսႽ ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1012955]
Approved by toolic
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (7)
As of 2014-12-29 13:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (188 votes), past polls