Mercurial > pub > Yours
view lib/Yours/Parsers/SaxParser.pm @ 0:93b83e3c38d6
initial commit
author | cin |
---|---|
date | Tue, 22 Oct 2013 05:26:56 +0400 |
parents | |
children | ae61af01bfa5 |
line wrap: on
line source
package Yours::Parsers::SaxParser; use strict; use IMPL::Const qw(:prop); use IMPL::declare { require => { XMLReader => 'XML::LibXML::Reader', Exception => 'IMPL::Exception', ArgException => '-IMPL::InvalidArgumentException' }, base => [ 'IMPL::Object' => undef ], props => [ _reader => PROP_RW ] }; BEGIN { XMLReader->import; } sub Parse { my ( $this, $options ) = @_; my $reader = $this->_reader( XMLReader->new($options) ); $reader->read(); $this->ProcessRootNode($reader); $reader->read(); } sub ProcessRootNode { my ( $this, $reader ) = @_; } sub ReadChildren { my ( $this, $handler ) = @_; my $reader = $this->_reader; return if $reader->isEmptyElement; my $currentLevel = $reader->depth; while ( $reader->read && ( $reader->depth > $currentLevel || $reader->nodeType != XML_READER_TYPE_END_ELEMENT ) ) { $this->$handler($reader) if $handler; } } sub ReadTextNode { my ($this) = @_; my $text = ""; my $handler; $handler = sub { my ( $me, $reader ) = @_; if ( $reader->nodeType == XML_READER_TYPE_TEXT ) { $text .= $reader->value; } else { $this->ReadChildren($handler); } }; $this->ReadChildren($handler); return $text; } sub ReadComplexNode { my ( $this, $schema ) = @_; if ( ref $schema eq 'HASH' ) { my %data; $this->ReadChildren( sub { my ( $me, $node ) = @_; my $name = $node->localName; if ( my $handler = $schema->{$name} ) { if (ref $handler eq 'ARRAY') { push @{$data{$name}}, $me->ReadComplexNode($$handler[0]); } else { $data{$name} = $me->ReadComplexNode($handler); } } else { $me->ReadChildren(); } } ); return \%data; } elsif ( ref $schema eq 'CODE' or not ref $schema ) { return $this->$schema($this->_reader); } else { die ArgException->new( schema => 'An invalid schema is supplied' ); } } sub attribute { shift->_reader->getAttribute(shift); } 1; __END__ =pod =head1 NAME =head1 DESCRIPTION =head1 MEMBERS =head2 ReadComplexNode($schema) =begin code { comments => sub { shift->ReadTextNode }, data => [ { location => sub { $_[1]->getAttribute('href')} , timestamp => 'ReadTextNode' } ] } =end code =cut