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

XML::Rules: Can hierarchy be changed?

by hoppfrosch (Scribe)
on Sep 29, 2010 at 11:03 UTC ( #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!

Comment on XML::Rules: Can hierarchy be changed?
Select or Download Code
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.

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.

Log In?
Username:
Password:

What's my password?
Create A New User
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? | Other CB clients
Other Users?
Others chanting in the Monastery: (13)
As of 2015-07-02 21:30 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (45 votes), past polls