Mercurial > pub > Impl
annotate Lib/IMPL/DOM/XMLReader.pm @ 143:d9dd3500ead3
Singleton behavior changed
| author | wizard | 
|---|---|
| date | Thu, 08 Jul 2010 23:46:49 +0400 | 
| parents | 7b14e0122b79 | 
| children | 1e7f03414b65 | 
| rev | line source | 
|---|---|
| 49 | 1 package IMPL::DOM::XMLReader; | 
| 2 use strict; | |
| 3 use warnings; | |
| 4 | |
| 5 use base qw(IMPL::Object IMPL::Object::Autofill); | |
| 6 use IMPL::Class::Property; | |
| 7 use IMPL::Class::Property::Direct; | |
| 8 use XML::Parser; | |
| 104 
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
 wizard parents: 
103diff
changeset | 9 require IMPL::DOM::Schema; | 
| 
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
 wizard parents: 
103diff
changeset | 10 require IMPL::DOM::Navigator::Builder; | 
| 
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
 wizard parents: 
103diff
changeset | 11 require IMPL::DOM::Navigator::SimpleBuilder; | 
| 49 | 12 | 
| 13 __PACKAGE__->PassThroughArgs; | |
| 14 | |
| 15 BEGIN { | |
| 16 public _direct property Navigator => prop_get | owner_set; | |
| 17 private _direct property _current => prop_all; | |
| 18 private _direct property _text => prop_all; | |
| 19 private _direct property _textHistory => prop_all; | |
| 20 } | |
| 21 | |
| 22 sub Parse { | |
| 23 my ($this,$in) = @_; | |
| 24 | |
| 25 my $parser = new XML::Parser( | |
| 26 Handlers => { | |
| 27 Start => sub {shift; goto &OnStart($this,@_)}, | |
| 28 End => sub {shift; goto &OnEnd($this,@_)}, | |
| 29 Char => sub {shift; goto &OnChar($this,@_)} | |
| 30 } | |
| 31 ); | |
| 32 | |
| 33 $parser->parse($in); | |
| 34 } | |
| 35 | |
| 36 sub ParseFile { | |
| 37 my ($this,$in) = @_; | |
| 38 | |
| 39 my $parser = new XML::Parser( | |
| 40 Handlers => { | |
| 41 Start => sub {shift; unshift @_, $this; goto &_OnBegin;}, | |
| 42 End => sub {shift; unshift @_, $this; goto &_OnEnd;}, | |
| 43 Char => sub {shift; unshift @_, $this; goto &_OnChar;} | |
| 44 } | |
| 45 ); | |
| 46 | |
| 47 $parser->parsefile($in); | |
| 48 } | |
| 49 | |
| 50 sub _OnBegin { | |
| 51 my ($this,$element,%attrs) = @_; | |
| 52 | |
| 53 push @{$this->{$_textHistory}},$this->{$_text}; | |
| 54 $this->{$_text} = ""; | |
| 55 $this->{$_current} = $this->Navigator->NavigateCreate($element,%attrs); | |
| 56 } | |
| 57 | |
| 58 sub _OnEnd { | |
| 59 my ($this,$element) = @_; | |
| 113 | 60 $this->{$_current}->nodeValue($this->Navigator->inflateValue( $this->{$_text} ) ) if length $this->{$_text}; | 
| 49 | 61 $this->{$_text} = pop @{$this->{$_textHistory}}; | 
| 62 $this->{$_current} = $this->Navigator->Back; | |
| 63 } | |
| 64 | |
| 65 sub _OnChar { | |
| 66 my ($this,$val) = @_; | |
| 67 $this->{$_text} .= $val; | |
| 68 } | |
| 69 | |
| 104 
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
 wizard parents: 
103diff
changeset | 70 sub LoadDocument { | 
| 
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
 wizard parents: 
103diff
changeset | 71 my ($self,$file,$schema) = @_; | 
| 
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
 wizard parents: 
103diff
changeset | 72 | 
| 
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
 wizard parents: 
103diff
changeset | 73 my $parser; | 
| 
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
 wizard parents: 
103diff
changeset | 74 if ($schema) { | 
| 
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
 wizard parents: 
103diff
changeset | 75 $schema = IMPL::DOM::Schema->LoadSchema($schema) if not ref $schema; | 
| 
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
 wizard parents: 
103diff
changeset | 76 $parser = $self->new( | 
| 
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
 wizard parents: 
103diff
changeset | 77 Navigator => IMPL::DOM::Navigator::Builder->new( | 
| 
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
 wizard parents: 
103diff
changeset | 78 'IMPL::DOM::Document', | 
| 
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
 wizard parents: 
103diff
changeset | 79 $schema | 
| 
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
 wizard parents: 
103diff
changeset | 80 ) | 
| 
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
 wizard parents: 
103diff
changeset | 81 ); | 
| 
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
 wizard parents: 
103diff
changeset | 82 } else { | 
| 
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
 wizard parents: 
103diff
changeset | 83 $parser = $self->new( | 
| 
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
 wizard parents: 
103diff
changeset | 84 Navigator => IMPL::DOM::Navigator::SimpleBuilder->new() | 
| 
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
 wizard parents: 
103diff
changeset | 85 ); | 
| 
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
 wizard parents: 
103diff
changeset | 86 } | 
| 
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
 wizard parents: 
103diff
changeset | 87 | 
| 
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
 wizard parents: 
103diff
changeset | 88 $parser->ParseFile($file); | 
| 
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
 wizard parents: 
103diff
changeset | 89 my $doc = $parser->Navigator->Document; | 
| 
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
 wizard parents: 
103diff
changeset | 90 if ($schema) { | 
| 
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
 wizard parents: 
103diff
changeset | 91 my @errors = $parser->Navigator->BuildErrors; | 
| 
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
 wizard parents: 
103diff
changeset | 92 push @errors, $schema->Validate($doc); | 
| 
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
 wizard parents: 
103diff
changeset | 93 die new IMPL::Exception("Loaded document doesn't match the schema", @errors) if @errors; | 
| 
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
 wizard parents: 
103diff
changeset | 94 } | 
| 
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
 wizard parents: 
103diff
changeset | 95 return $doc; | 
| 
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
 wizard parents: 
103diff
changeset | 96 } | 
| 
196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
 wizard parents: 
103diff
changeset | 97 | 
| 49 | 98 1; | 
| 99 | |
| 100 __END__ | |
| 101 | |
| 102 =pod | |
| 103 | |
| 104 =head1 SYNOPSIS | |
| 105 | |
| 106 my $reader = new IMPL::DOM::XMLReader(Navigator => $DomBuilder); | |
| 107 my $obj = $reader->parsefile("data.xml"); | |
| 108 | |
| 109 =head1 DESCRIPTION | |
| 110 | |
| 111 Простой класс, использующий навигатор для постороения документа. В зависимости от | |
| 112 используемого навигатора может быть получен различный результат. | |
| 113 | |
| 114 Навигатор должен поодерживать методы C<NavigateCreate> и C<Back> | |
| 115 | |
| 116 =head1 METHODS | |
| 117 | |
| 118 =over | |
| 119 | |
| 120 =item C<CTOR(Naviagtor => $builder)> | |
| 121 | |
| 122 Создает новый экземпляр парсера, с указанным навигатором для построения документа | |
| 123 | |
| 124 =item C<$obj->Parse($in)> | |
| 125 | |
| 126 Строит документ. На вход получает либо xml строку, либо HANDLE. | |
| 127 | |
| 128 =item C<$obj->ParseFile($fileName)> | |
| 129 | |
| 130 Строит документ из файла с именем C<$fileName>. | |
| 131 | |
| 132 =back | |
| 133 | |
| 134 =cut | 
