Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Re: XML::Rules parsing inside out?

by runrig (Abbot)
on Dec 07, 2017 at 22:22 UTC ( #1205125=note: print w/replies, xml ) Need Help??


in reply to XML::Rules parsing inside out?

XML::Rules is infinitely better than XML::Simple. You don't seem to understand that a tag is not fully 'parsed' until the end of the tag is reached. If you want to catch the start of the tag (along with its attributes), then use a start tag rule (either prefix the tag with "^", or use the 'start_rules' argument).

This is sensible because you cannot pass the contents of inner tags up to the outer tag rules (which is possible with XML::Rules) until the end tag of the outer XML tag is reached.

Replies are listed 'Best First'.
Re^2: XML::Rules parsing inside out?
by runrig (Abbot) on Dec 07, 2017 at 22:38 UTC
    Here's an (untested) example:
    use XML::Rules; use Data::Dumper; my %tag_value; my $tag_name; my $xr = XML::Rules->new( rules => [ value => sub { $tag_value{$tag_name} = $_[1]->{_content} +], start_rules => [ 'summary,detail1,detail2' => sub { $tag_name = $_[0 +] } ], ); $xr->parse($xml) # I left the xml out print Dumper \%tag_value;
    Note that this could be done much differently by passing the 'value' content up through the 'item' tag to the item's parent tag, returning the entire data structure. I'll leave that as an exercise...(Hint: use the 'content' rule for value and 'pass no content' for item tags, and 'no content by <attr>' for the other tags).
Re^2: XML::Rules parsing inside out?
by bfdi533 (Friar) on Dec 07, 2017 at 23:07 UTC

    Good explanation and I did some more digging and found that $_[2] is an array of the prior tags in the "stack".

    So, if I do the following I can determine which item I am in and handle appropriately:

    'item' => sub { my $in_item = $_[2][$#{$_[2]}]; if ($in_item eq "summary") { $hash{summary} = $_[1]->{value}; } if ($in_item eq "detail1") { $hash{detail1} = $_[1]->{value}; } if ($in_item eq "detail2") { $hash{detail2} = $_[1]->{value}; } }

    This gets me what I want perfectly! Obviously my actual XMl is much more complicated than this contrived example (and I actually have an array of items in detail2 (sometimes) so this works quite well to determine what 'value' belongs to.

    Thank you for the time to answer and steer me in my research to get where I need to go.

      Good explanation and I did some more digging ... This gets me what I want perfectly! Obviously my actual XMl is much more complicated than this contrived example

      Why XML::Rules?

      To me this is clearly XML::Twig or xpath territory

        I've found XML::Rules pretty easy to use, so I'm not clear on why you think this is clearly XML::Twig domain.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (2)
As of 2023-11-30 18:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?