http://www.perlmonks.org?node_id=999895

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

Can anyone help me change Handlers in XML::Parser?

Code excerpt is as follows:

#!/usr/bin/perl -w use strict; use XML::Parser; open (FILEA, "File.txt"); my $parser = XML::Parser->new(); $parser->setHandlers(Start => \&handle_start, Char => \&handle_char, End => \&handle_end1, Final => \&final1); $parser-parsefile('File2.txt'); my $char_array_ref; my @end_array; sub handle_start{ my $e = shift; my $start_element = shift; if ($start_element eq 'coordinates'){print "hello.\n"; $parser->setHandlers(Char => \&coord); } } sub handle_char{ my $e = shift; print "HELLO There\n."; } sub coord{ my $e = shift; print "hello again.\n"; }

Use of print commands serve as a test to see which subroutines are called on Char events.

I never see "hello again" printed to the screen.

The Expat documentation suggests that you can change a handler conditionally as I am trying to do.

But I cannot seem to get it to work.

Can anyone point me in the right direction?

I would be very much obliged.

Thanks

Replies are listed 'Best First'.
Re: change setHandlers XML::Parser
by Anonymous Monk on Oct 19, 2012 at 10:07 UTC
Re: change setHandlers XML::Parser
by Jenda (Abbot) on Oct 19, 2012 at 21:42 UTC

    XML::Parser is a little too low-level. What is it you are trying to achieve?

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

      Thanks, Jenda, and Anonymous Monk, I am trying to parse through a huge kml file that contains longitude and latitude coordinates for census blocks and pull out only those long and lat coords that pertain to certain blocks within a subset of census tracts. I will have CDATA information to parse through to get the tract and block numbers, but right now I am just trying to test code on pulling out the long and lat coordinates that are denoted by a <coordinates> tag in the xml.

      In other words, right now, I want to extract information only if the Start handler indicates a <coordinates> tag. That's why I am looking for a way to conditionally switch to a different handler.

      Sorry for the long-winded answer.

      Hope this helps.

      XML::Twig looks interesting, but I was hoping to stick with a more SAX-like parser rather than DOM-like or pull-parser like.

      Would you also suggest XML::Twig?

      Thanks again.

        You can ask XML::Twig to give you just the tag(s) you are interested in (twig_root) and handle them by a custom subroutine. Or you can have a look at XML::Rules and basically do the same. Or if you were so inclined use XML::LibXML::SAX.

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

        XML::Twig looks interesting, but I was hoping to stick with a more SAX-like parser rather than DOM-like or pull-parser like.

        XML::Twig is super flexible, its SAX+DOM or SAX or DOM.

        Rarely do you want to use the SAX feature alone, mostly its SAX+DOM (SAX+TWIG, only a little piece of DOM).

        Re: XML::Twig n00b

        $ perl use XML::Twig ; XML::Twig->new( twig_handlers => { 'coordinates' => sub { print $_->xpath, "\n"; print $_->trimmed_text, "\n\n"; }, }, )->xparse( "somefile.xml" ); __END__ /on/no/coordinates ro /on/ma/to/peia/coordinates sham /on/coordinates bo /on/coordinates[2] <b>Asin</b> (I) - Biography $ cat somefile.xml <on> <no><coordinates>ro</coordinates></no> <ma><to><peia><coordinates>sham</coordinates></peia></to></ma> <coordinates>bo</coordinates> <coordinates><![CDATA[<b>Asin</b> (I) - Biography]]></coordinates> </on>