Mercurial > pub > Impl
changeset 125:a4b0a819bbda
Small fixes in IMPL::DOM::Schema
author | wizard |
---|---|
date | Thu, 10 Jun 2010 17:43:51 +0400 |
parents | e30bdd040fe3 |
children | c8dfbbdd8005 |
files | Lib/IMPL/DOM/Schema/ComplexType.pm Lib/IMPL/DOM/Schema/NodeList.pm Lib/IMPL/DOM/Schema/NodeSet.pm Lib/IMPL/DOM/Schema/SwitchNode.pm Lib/IMPL/DOM/Schema/ValidationError.pm Lib/IMPL/DOM/Schema/Validator/Compare.pm _test/Web.t _test/temp.pl |
diffstat | 8 files changed, 106 insertions(+), 20 deletions(-) [+] |
line wrap: on
line diff
--- a/Lib/IMPL/DOM/Schema/ComplexType.pm Thu Jun 10 02:45:59 2010 +0400 +++ b/Lib/IMPL/DOM/Schema/ComplexType.pm Thu Jun 10 17:43:51 2010 +0400 @@ -36,7 +36,7 @@ if ($this->{$nativeType}) { return new IMPL::DOM::Schema::ValidationError( Node => $node, - Source => $ctx && $ctx->{Source} || $this, + Source => $ctx->{Source} || $this, Schema => $this, Message => $this->messageWrongType ) unless $node->isa($this->{$nativeType});
--- a/Lib/IMPL/DOM/Schema/NodeList.pm Thu Jun 10 02:45:59 2010 +0400 +++ b/Lib/IMPL/DOM/Schema/NodeList.pm Thu Jun 10 17:43:51 2010 +0400 @@ -23,13 +23,14 @@ } sub Validate { - my ($this,$node) = @_; + my ($this,$node,$ctx) = @_; my @nodes = map { {nodeName => $_->name, anyNode => $_->isa('IMPL::DOM::Schema::AnyNode') , Schema => $_, Max => $_->maxOccur eq 'unbounded' ? undef : $_->maxOccur, Min => $_->minOccur, Seen => 0 } } @{$this->childNodes}; my $info = shift @nodes; + my $sourceSchema = $ctx->{Source} || $this->parentNode; foreach my $child ( @{$node->childNodes} ) { #skip schema elements @@ -40,7 +41,7 @@ Node => $child, Parent => $node, Schema => $info->{Schema}, - Source => $this + Source => $sourceSchema ) if $info->{Min} > $info->{Seen}; $info = shift @nodes; @@ -51,7 +52,7 @@ Message => $this->messageUnexpected, Node => $child, Parent => $node, - Source => $this + Source => $sourceSchema ) unless $info; # it's ok, we found schema element for child @@ -74,7 +75,7 @@ Message => $this->messageUnexpected, Node => $child, Parent => $node, - Source => $this, + Source => $sourceSchema, ) if $info->{Max} and $info->{Seen} > $info->{Max}; } @@ -83,7 +84,7 @@ return new IMPL::DOM::Schema::ValidationError ( Error => 1, Message => $this->messageNodesRequired, - Source => $this, + Source => $sourceSchema, Parent => $node, Schema => $info->{Schema} ) if $info->{Seen} < $info->{Min};
--- a/Lib/IMPL/DOM/Schema/NodeSet.pm Thu Jun 10 02:45:59 2010 +0400 +++ b/Lib/IMPL/DOM/Schema/NodeSet.pm Thu Jun 10 17:43:51 2010 +0400 @@ -24,12 +24,14 @@ } sub Validate { - my ($this,$node) = @_; + my ($this,$node,$ctx) = @_; my @errors; my %nodes; my $anyNode; + my $sourceSchema = $ctx->{Source} || $this->parentNode; + foreach (@{$this->childNodes}) { if ($_->isa('IMPL::DOM::Schema::AnyNode')) { $anyNode = {Schema => $_, Min => $_->minOccur, Max => $_->maxOccur eq 'unbounded' ? undef : $_->maxOccur , Seen => 0 }; @@ -42,7 +44,7 @@ if (my $info = $nodes{$child->nodeName} || $anyNode) { $info->{Seen}++; push @errors,new IMPL::DOM::Schema::ValidationError ( - Source => $this, + Source => $sourceSchema, Node => $child, Parent => $node, Schema => $info->{Schema}, @@ -54,7 +56,7 @@ } } else { push @errors, new IMPL::DOM::Schema::ValidationError ( - Source => $this, + Source => $sourceSchema, Node => $child, Parent => $node, Message => $this->messageUnexpected @@ -64,7 +66,7 @@ foreach my $info (values %nodes) { push @errors, new IMPL::DOM::Schema::ValidationError ( - Source => $this, + Source => $sourceSchema, Schema => $info->{Schema}, Parent => $node, Message => $this->messageMin
--- a/Lib/IMPL/DOM/Schema/SwitchNode.pm Thu Jun 10 02:45:59 2010 +0400 +++ b/Lib/IMPL/DOM/Schema/SwitchNode.pm Thu Jun 10 17:43:51 2010 +0400 @@ -23,12 +23,12 @@ sub CTOR { my ($this,%args) = @_; - $this->messageNoMatch($args{messageNoMatch} || 'A node %Node.nodeName% isn\'t expected in the %Node.parentNode.path%'); + $this->messageNoMatch($args{messageNoMatch} || 'A node %Node.nodeName% isn\'t expected in the %Parent.path%'); } sub Validate { - my ($this,$node) = @_; - + my ($this,$node,$ctx) = @_; + if ( my ($schema) = $this->selectNodes(sub {$_[0]->name eq $node->nodeName} ) ) { return $schema->Validate($node); } else {
--- a/Lib/IMPL/DOM/Schema/ValidationError.pm Thu Jun 10 02:45:59 2010 +0400 +++ b/Lib/IMPL/DOM/Schema/ValidationError.pm Thu Jun 10 17:43:51 2010 +0400 @@ -25,7 +25,13 @@ $this->{$Node} = $args{Node}; $this->{$Schema} = $args{Schema} if $args{Schema}; $this->{$Source} = $args{Source} if $args{Source}; - $this->{$Parent} = $args{Parent} if $args{Parent}; + if ($args{Parent}) { + $this->{$Parent} = $args{Parent}; + } elsif ($args{Node}) { + $this->{$Parent} = $args{Node}->parentNode; + } else { + die new IMPL::InvalidArgumentException("A 'Parent' or a 'Node' parameter is required"); + } $this->{$Message} = FormatMessage(delete $args{Message}, \%args) if $args{Message}; } @@ -35,3 +41,81 @@ } 1; + +__END__ + +=pod + +=head1 NAME + +C<IMPL::DOM::Schema::ValidationError> - Описывает ошибку в документе. + +=head1 DESCRIPTION + +При проверке документа на ошибки формирования возвращается массив с объектами +C<IMPL::DOM::Schema::ValidationError>, каждая из которых описывает одну ошибку +в документе. + +С помощью данного объекта осущетсвляется привязка элемента схемы, элемента документа +и сообщения о причине возникновения ошибки. + +=head1 MEMBERS + +=over +=item C<[get] Node> + + +Узел в документе который привел к ошибке. Как правило это либо простые узлы, либо +узлы, которые не могут присутствоать в данном месте по схеме. + +Данное свойство может быть C<undef>. + +=item C<[get] Parent> + +Родительский узел в котором произошла ошибка. Используется в случаях, когда C<Node> +не указан, например, если по схеме должен существовать дочерний узел с определенным +именем, а в реальном документе его нет. + +Также это свойство может использоваться при формировании сообщения. + +=item C<[get] Schema> + +Схема для C<Node> или узла который должен присутсвовать если C<Node> не задан. + +=item C<[get] Source> + +Схема, проверка которой привела к возникновению ошибки. Поскольку схемы могут +использовать ссылки, то данное свойство нужно для получения схемы узла, а не +схемы его типа. + +Тоесть проверка схемы узла C<IMPL::DOM::Schema::Node> приводит к проверке схемы +типа, например, C<IMPL::DOM::Schema::ComplexType>, а свойство C<Source> будет +указывать именно на C<IMPL::DOM::Schema::Node>. + +=item C<[get] Message> + +Возвращает форматированное сообщение об ошибке. + +=item C<toString()> + +Преобразует ошибку к строке, возвращает значение свойства C<Message> + +=back + +=head1 REMARKS + +=begin code + +my $doc = IMPL::DOM::XMLReader->LoadDocument('data.xml'); +my $schema = IMPL::DOM::Schema->LoadSchema('schema.xml'); + +my @errors = $schema->Validate($doc); + +my $node = $doc->selectSingleNode('user','name'); + +# Получаем все ошибки относящиеся к данному узлу +my @nodeErrors = grep { ($_->Node || $_->Parent) == $node } @errors; + +=end code + +=cut
--- a/Lib/IMPL/DOM/Schema/Validator/Compare.pm Thu Jun 10 02:45:59 2010 +0400 +++ b/Lib/IMPL/DOM/Schema/Validator/Compare.pm Thu Jun 10 17:43:51 2010 +0400 @@ -9,7 +9,7 @@ BEGIN { public property targetProperty => prop_all; public property op => prop_all; - public property nodePath => prop_get | owner_set; + public property nodePath => prop_all; public property optional => prop_all; private property _pathTranslated => prop_all; private property _targetNode => prop_all; @@ -20,6 +20,7 @@ 'IMPL::DOM::Schema::Validator' => sub { my %args = @_; $args{nodeName} ||= 'Compare'; + delete @args{qw(targetProperty op nodePath optional message)}; %args; } ); @@ -114,7 +115,7 @@ my $query = $this->_pathTranslated() || $this->_pathTranslated($this->TranslatePath($this->nodePath)); - my ($foreignNode) = $node->selectNodes($query); + my ($foreignNode) = $node->selectNodes(@$query); my $Source = $ctx && $ctx->{Source} || $this->parentNode;