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