Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

XML::Rules: Can hierarchy be changed?

by hoppfrosch (Scribe)
on Sep 29, 2010 at 11:03 UTC ( [id://862589]=perlquestion: print w/replies, xml ) Need Help??

hoppfrosch has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I've got a simple xml:
<root> <parent>p1 p2 <ch1>c1_1</ch1> p3 <ch2>c2</ch2> p4 <ch1>c1_2</ch1> p5 +</parent> </root>
What I want to do is parsing this into a hash:
'root' => { 'parent' => [ { 'text' => 'p1 p2 p3 p4 p5' 'ch2' => [ 'c2' ], 'ch1' => [ 'c1_1', 'c1_2' ] } ] }
What I tried is (with XML::Rules):
my $parser = XML::Rules->new ( rules => [ root => 'no content', parent => 'no content array', ch1 => 'content array', ch2 => 'content array', ] ); my $result = $parser->parsestring($xml);
What I cannot figure out yet, is howto parse the "contents" of tag <parent> (I have to consider "p1 p2 "." p3 "." p4 "." p5" as content for some reason) into a child "text" of the item "parent" in my (desired) hash .... I tried several things like
# different Rule for "parent" parent => sub {$_[0]->{text} => $_[1]->{_content}},
but had no success yet ... (It's clear that above syntax does not make sense - but I think it expresses what I want to achieve)
Any help welcome!

Replies are listed 'Best First'.
Re: XML::Rules: Can hierarchy be changed?
by Jenda (Abbot) on Sep 30, 2010 at 07:47 UTC
    my $parser = XML::Rules->new ( rules => [ root => 'no content', parent => sub {$_[1]->{text} = delete $_[1]->{_content}; return '@ +parent' => $_[1]}, ch1 => 'content array', ch2 => 'content array', ] );

    The attributes are all in the hash referenced by $_[1], the $_[0] is just a string. So in the rule for <parent> you first move the text content from {_content} to {text} and then return the tag name and attributes prepending the '@' to make sure you end up with an array of parents. See the builtin rules in XML::Rules docs and especially the sub{} next to the 'as array' rule.

    Jenda
    Enoch was right!
    Enjoy the last years of Rome.

Re: XML::Rules: Can hierarchy be changed?
by murugu (Curate) on Sep 30, 2010 at 05:39 UTC
    hoppfrosch,

    Below code should form the required data structure as mentioned by you in the question. By the way i cant commit that my code is the efficient answer. Other revered monks will be able to give you the answers in most efficient way

    #!/usr/bin/perl use strict; use XML::Rules; use Data::Dumper; my $xml = q(<root> <parent>p1 p2 <ch1>c1_1</ch1> p3 <ch2>c2</ch2> p4 <ch1>c1_2</ch1> p5 +</parent> </root>); my $parser = XML::Rules->new ( rules => [ root => 'no content', parent => sub { $_[1]->{text} = $_[1]->{_content}, delete $_[1] +->{_content}, return ($_[0] => [$_[1]] , [$_[0] => $_[1]])} , ch1 => 'content array', ch2 => 'content array', ] ); my $result = $parser->parsestring($xml); print Dumper $result;

    Regards,
    Murugesan Kandasamy
    use perl for(;;);

      sub { $_[1]->{text} = $_[1]->{_content}, delete $_[1]->{_content}, ret +urn ($_[0] => [$_[1]] , [$_[0] => $_[1]])}
      is better written as
      sub { $_[1]->{text} = $_[1]->{_content}; delete $_[1]->{_content}; ret +urn ($_[0] => [$_[1]] , [$_[0] => $_[1]])}
      You can put several statements into an anonymous subroutine so no need to use commas where you mean semicolons :-)

      Jenda
      Enoch was right!
      Enjoy the last years of Rome.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (7)
As of 2024-04-18 14:03 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found