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