NAME

XML::Parser::Expat::Dispatched - Automagically dispatches subs to XML::Parser::Expat handlers

VERSION

version 0.952

SYNOPSIS

package MyParser;
use parent XML::Parser::Expat::Dispatched;

sub Start_tagname{
  my $self = shift;
  say $_[0], $self->original_tagname;
}

sub End_tagname{
  my $self=shift;
  say "$_[0] ended";
}

sub Char_handler{
  my ($self, $string) = @_;
  say $string;
}

sub config_dispatched{{
  transform => sub{lc $_[1]}
}}

 package main;
 my $p = MyParser->new;
 $p->parse('<Tagname>tag</Tagname>');
 # prints
 # Tagname<Tagname>
 # tag
 # Tagname ended

DESCRIPTION

This package provides a new method that produces some dispatch methods for "set_handlers" in XML::Parser::Expat.

If you were using XML::Parser::Expat for parsing your XML, you'd probably end up with something like this:

use XML::Parser::Expat;
my $p = XML::Parser::Expat->new();
$p->set_handlers(Start => \&sh,
                 End   => \&eh,
                 Char => sub{print "in String"});

sub sh{
  my $p = shift;
  given($_[0]){
    when('employer'){...}
    when('employee'){...}
    when('date'){...}
  }
}

sub eh{
  my $p = shift;
  given($_[0]){
    when('employer'){...}
    when('employee'){...}
    when('date'){...}
  }
}

With this Module your dispatching will be done based on your methods:

package myexpatparser;

use parent 'XML::Parser::Expat::Dispatched';

sub Start_employer{...}
sub Start_employee{...}
sub Start_date{...}

sub End_employer{...}
sub End_employee{...}
sub End_date{...}

sub Char_handler{print "in String"}

package main;
use myexpatparser;
myexpatparser->new;

I wrote this module because i needed a quite low-level XML-Parsing library that had an original_string method. So if you need some higher level library, I'd really suggest to look at the "SEE ALSO" section.

Since your package will inherit XML::Parser::Expat be prepared to call it's release-method if you write your own DESTROY-method.

HANDLERS

Available handlers:

The underscore in the subroutine names is optional for all the handler methods. The arguments your subroutine gets called with, are the same as those for the handlers from XML::Parser::Expat.

Start_tagname

Will be called when a start-tag is encountered that matches tagname. If tagname is not given (when your sub is called Start or Start_), it works like a default-handler for start tags.

End_tagname

Will be called when a end-tag is encountered that matches tagname. If tagname is not given (when your sub is called End or End_), it works like a default-handler for end tags.

Handler_handler

Installs this subroutine as a handler for XML::Parser::Expat. You can see the Handler names on "set_handlers" in XML::Parser::Expat. Notice that if you try to define a handler for Start or End, they will be interpreted as Start or End handlers for handler-tags, use subs called Start or End instead.

config_dispatched

This handler is special: You can return a hashref with configuration options for config_dispatched.

Available options and default values are:

  • Start[Start]: Part of the sub name that marks a Start handler

  • End[End]: Part of the sub name that marks an End handler

  • handler[handler]: Part of the sub name that marks that this is a handler subroutine other than Start and End

These options are for transforming the subroutine names and the tagnames. They always get called with the parser and the string to transform as arguments. (Think transform_tag($tagname) eq transform_suffix($subname =~ /Start_?(.*)/))

  • transform_tag: Will be called for each tag. The return value of this sub will be compared to the subname prefixes.

  • transform_suffix: Will be called for each subroutine name. The retrun value of this sub will be compared to the tagnames.

  • transform: Sets both transform_tag and transform_suffix to the given value.

Some Examples:

sub config_dispatched{{
  Start     => 'begin',
  End       => 'finish',
  transform => sub{lc $_[1]}, # now matching is case insensitive
}}

sub config_dispatched{{
  transform_tag => sub{return $_[1]=~/:([^:]+)$/ ? $1: $_[1]},
  # try to discard namespace prefixes
}}

sub config_dispatched{{
  transform_suffix => sub{my $_ =  $_[1]; s/__/:/g; s/_/-/g; $_},
  # try to work around the fact that `-' and `:' aren't allowed characters for perl subroutine names
}}

Note that the allowed characters for perl's subroutine names and XML-Identifiers aren't the same, so you might want to use the default handlers or transform_gi in some cases (namespaces, tagnames with a dash).

DIAGNOSTICS

the sub %s1 overrides the handler for %s2

You most probably have two subroutines that have the same name exept one with an underscore and one without. The warning issued tells you wich of the subroutines will be used as a handler. Since the underlying mechanism is based on the each iterator, this behavior can vary from time to time running, so you might want to change your sub names.

%s1 and %s2 translate to the same handler

There is an sub called %s1 that translates to the same handler as a sub %s2 after applying transform_gi. The sub %s1 will be used.

INTERNALS

The following things might break this module so be aware of them:

* Your parser will be a XML::Parser::Expat so consider checking the methods of this class if you write methods other than handler methods . * Using AUTOLOAD without updating the symbol table before new is called.

* Calling set_handlers on your parser. This module calls set_handlers and if you do, you overwrite the handlers it had installed (why do you use this module anyway?).

SEE ALSO

Obviously XML::Parser::Expat as it is a simple extension of that class.

You also should chekout these modules for parsing XML:

AUTHOR

Patrick Seebauer <patpatpat@cpan.org>

COPYRIGHT AND LICENSE

This software is copyright (c) 2013 by Patrick Seebauer.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.