Mercurial > pub > Impl
comparison Lib/IMPL/DOM/Navigator/SchemaNavigator.pm @ 104:196bf443b5e1
DOM::Schema RC0 inflators support, validation and some other things,
Minor and major fixes almost for everything.
A 'Source' property of the ValidationErrors generated from a NodeSet or a NodeList is subject to change in the future.
| author | wizard |
|---|---|
| date | Tue, 11 May 2010 02:42:59 +0400 |
| parents | c289ed9662ca |
| children | 76515373dac0 |
comparison
equal
deleted
inserted
replaced
| 103:c289ed9662ca | 104:196bf443b5e1 |
|---|---|
| 36 | 36 |
| 37 die new IMPL::InvalidArgumentException('name is required') unless defined $name; | 37 die new IMPL::InvalidArgumentException('name is required') unless defined $name; |
| 38 | 38 |
| 39 # perform a safe navigation | 39 # perform a safe navigation |
| 40 #return dosafe $this sub { | 40 #return dosafe $this sub { |
| 41 my $steps = 1; | 41 my $steps = 0; |
| 42 # if we are currently in a ComplexNode, first go to it's content | |
| 43 if ($this->Current->isa('IMPL::DOM::Schema::ComplexNode')) { | |
| 44 # navigate to it's content | |
| 45 # ComplexNode | |
| 46 $this->internalNavigateNodeSet($this->Current->content); | |
| 47 $steps ++; | |
| 48 } | |
| 49 | |
| 42 # navigate to node | 50 # navigate to node |
| 43 if ( | 51 if ( |
| 44 my $node = $this->Navigate( sub { | 52 my $node = $this->Navigate( sub { |
| 45 $_->isa('IMPL::DOM::Schema::Node') and ( | 53 $_->isa('IMPL::DOM::Schema::Node') and ( |
| 46 $_->name eq $name | 54 $_->name eq $name |
| 49 or | 57 or |
| 50 ( $_->nodeName eq 'SwitchNode' and $_->selectNodes( sub { $_->name eq $name } ) ) | 58 ( $_->nodeName eq 'SwitchNode' and $_->selectNodes( sub { $_->name eq $name } ) ) |
| 51 ) | 59 ) |
| 52 }) | 60 }) |
| 53 ) { | 61 ) { |
| 62 $steps ++; | |
| 54 if ($node->nodeName eq 'AnyNode') { | 63 if ($node->nodeName eq 'AnyNode') { |
| 55 # if we navigate to the anynode | 64 # if we navigate to the anynode |
| 56 # assume it to be ComplexType by default | 65 # assume it to be ComplexType by default |
| 57 $node = $node->type ? $this->{$Schema}->resolveType($node->type) : $schemaAnyNode; | 66 $node = $node->type ? $this->{$Schema}->resolveType($node->type) : $schemaAnyNode; |
| 67 $this->internalNavigateNodeSet($node); | |
| 68 $steps ++; | |
| 58 } elsif ($node->nodeName eq 'SwitchNode') { | 69 } elsif ($node->nodeName eq 'SwitchNode') { |
| 59 # if we are in the switchnode | 70 # if we are in the switchnode |
| 60 # navigate to the target node | 71 # navigate to the target node |
| 61 $node = $this->Navigate(sub { $_->name eq $name }); | 72 $node = $this->Navigate(sub { $_->name eq $name }); |
| 62 $steps ++; | 73 $steps ++; |
| 67 # resolve it | 78 # resolve it |
| 68 $node = $this->{$Schema}->resolveType($node->type); | 79 $node = $this->{$Schema}->resolveType($node->type); |
| 69 $this->internalNavigateNodeSet($node); | 80 $this->internalNavigateNodeSet($node); |
| 70 $steps++; | 81 $steps++; |
| 71 } | 82 } |
| 72 | |
| 73 # if target node is a complex node | |
| 74 if ($node->isa('IMPL::DOM::Schema::ComplexNode')) { | |
| 75 # navigate to it's content | |
| 76 $this->internalNavigateNodeSet($node->content); | |
| 77 $steps ++; | |
| 78 } | |
| 79 | 83 |
| 80 push @{$this->{$_historySteps}},$steps; | 84 push @{$this->{$_historySteps}},$steps; |
| 81 | 85 |
| 82 # return found node schema | 86 # return found node schema |
| 83 return $node; | 87 return $node; |
| 91 my ($this) = @_; | 95 my ($this) = @_; |
| 92 | 96 |
| 93 $this->Back(pop @{$this->{$_historySteps}}) if $this->{$_historySteps}; | 97 $this->Back(pop @{$this->{$_historySteps}}) if $this->{$_historySteps}; |
| 94 } | 98 } |
| 95 | 99 |
| 100 sub SourceSchemaNode { | |
| 101 my ($this) = @_; | |
| 102 | |
| 103 if ($this->Current->isa('IMPL::DOM::Schema::SimpleType') or | |
| 104 $this->Current->isa('IMPL::DOM::Schema::ComplexType') | |
| 105 ) { | |
| 106 # we a redirected | |
| 107 return $this->GetNodeFromHistory(-1); | |
| 108 } else { | |
| 109 return $this->Current; | |
| 110 } | |
| 111 } | |
| 112 | |
| 96 1; | 113 1; |
| 97 __END__ | 114 __END__ |
| 98 | 115 |
| 99 =pod | 116 =pod |
| 100 | 117 |
| 105 | 122 |
| 106 =head1 METHODS | 123 =head1 METHODS |
| 107 | 124 |
| 108 =over | 125 =over |
| 109 | 126 |
| 110 =item C<< $navi->NavigateName($name) >> | 127 =item C<NavigateName($name)> |
| 111 | 128 |
| 112 Переходит на схему узла с указанным именем. Тоесть использует свойство C<name>. | 129 Переходит на схему узла с указанным именем. Тоесть использует свойство C<name>. |
| 113 | 130 |
| 114 =item C<< $navi->SchemaBack >> | 131 =item C<SchemaBack> |
| 115 | 132 |
| 116 Возвращается на позицию до последней операции C<NavigateName>. Данный метод нужен | 133 Возвращается на позицию до последней операции C<NavigateName>. Данный метод нужен |
| 117 посокольку операция навигации по элементам описываемым схемой может приводить к | 134 посокольку операция навигации по элементам описываемым схемой может приводить к |
| 118 нескольким операциям навигации по самой схеме. | 135 нескольким операциям навигации по самой схеме. |
| 119 | 136 |
| 137 =item C<SourceSchemaNode> | |
| 138 | |
| 139 Получает схему узла из которого было выполнено перенаправление, например, C<IMPL::DOM::Schema::Node>. | |
| 140 В остальных случаях совпадает со свойством C<Current>. | |
| 141 | |
| 120 =back | 142 =back |
| 121 | 143 |
| 122 =cut | 144 =cut |
