Mercurial > pub > Impl
view Lib/IMPL/DOM/Navigator/Builder.pm @ 23:716b287d4795
merge
author | Sergey |
---|---|
date | Wed, 30 Sep 2009 17:43:52 +0400 |
parents | 75d55f4ee263 |
children | 7f00786f8210 |
line wrap: on
line source
package IMPL::DOM::Navigator::Builder; use strict; use warnings; use base qw(IMPL::DOM::Navigator); use IMPL::Class::Property; use IMPL::Class::Property::Direct; BEGIN { protected _direct property _navigatorSchema => prop_all; public _direct property Document => prop_get | owner_set; } our %CTOR = ( 'IMPL::DOM::Navigator' => sub { $_[0] } # IMPL::DOM::Navigator($domDocument) ); sub CTOR { my ($this,$domDocument,$schema) = @_; $this->{$Document} = $domDocument; $this->{$_navigatorSchema} = new IMPL::DOM::Navigator($schema); } sub NavigateCreate { my ($this,$nodeName,%props) = @_; if ( my $nodeSchema = $this->{$_navigatorSchema}->Navigate(sub { $_[0]->nodeName eq $nodeName or $_[0]->isa('IMPL::DOM::Schema::AnyNode') }) ) { my $class = delete $props{type} || $nodeSchema->type || $nodeName; my $node = $this->{$Document}->Create(delete $props{nodeName} || $nodeName, $class, \%props); $this->Current()->appendNode($node); $this->Current($node); } else { die new IMPL::InvalidOperationException("Requested elemnt not found in the schema"); } } sub Back { my ($this) = @_; $this->{$_navigatorSchema}->Back; return $this->SUPER::Back(); } 1; __END__ =pod =head1 SYNOPSIS my $builder = new IMPL::DOM::Navigator::Builder(new MyApp::Document,$schema); my $reader = new IMPL::DOM::XMLReader(Navigator => $builder); $reader->ParseFile("document.xml"); my @errors = $schema->Validate($builder->Document); =head1 DESCRIPTION Построитель DOM документов по указанной схеме. Обычно используется в связке с объектами для чтения такими как C<IMPL::DOM::XMLReader>. =head1 METHODS =over =item C<CTOR($domDocument,$schema)> Создает новый объект, принимает на вход пустой (но не обязательно) документ и схему. =item C<< $obj->NavigateCreate($nodeName) >> Создает новый узел с указанным именем и переходит в него. В случае если в схеме подходящий узел не найден, то вызывается исключение. При этом схема узла производится по имени, после чего определяется класс для создания узла, по алгоритму =over =item Проверяется свойство C<type> и если оно есть, то используется оно =item Проверяется свойство C<type> самого элемента схемы, если оно есть, то используется оно. =item В качестве класса берется имя узла =back Также имя создаваемого узла может быть переопределено свойством C<nodeName>. Т.о. узел вида C<< <ComplexNode nodeName="Box" type="Container"> >> приведет к созданию C<< Container->new(nodeName => 'Box') >>. =back =cut