diff Lib/IMPL/DOM/Schema/NodeSet.pm @ 19:1ca530e5c9c5

DOM схема, требует переработки в части схемы для описания схем. Автоверификация не проходит
author Sergey
date Fri, 11 Sep 2009 16:30:39 +0400
parents 94d47b388442
children 267460284fb3
line wrap: on
line diff
--- a/Lib/IMPL/DOM/Schema/NodeSet.pm	Thu Sep 10 17:42:47 2009 +0400
+++ b/Lib/IMPL/DOM/Schema/NodeSet.pm	Fri Sep 11 16:30:39 2009 +0400
@@ -2,13 +2,25 @@
 use strict;
 use warnings;
 
-use base qw(IMPL::DOM::Schema::Item);
+use base qw(IMPL::DOM::Node);
 use IMPL::Class::Property;
 
+our %CTOR = (
+    'IMPL::DOM::Node' => sub { nodeName => 'NodeSet' }
+);
+
 BEGIN {
-    public property UnexpectedMessage => prop_all;
-    public property MaxMessage => prop_all;
-    public property MinMessage => prop_all;
+    public property messageUnexpected => prop_all;
+    public property messageMax => prop_all;
+    public property messageMin => prop_all;
+}
+
+sub CTOR {
+    my ($this,%args) = @_;
+    
+    $this->messageMax( $args{messageMax} || 'Too many %Node.nodeName% nodes');
+    $this->messageMin( $args{messageMin} || '%Schema.nodeName% nodes expected');
+    $this->messageUnexpected( $args{messageUnexpected} || 'A %Node.nodeName% isn\'t allowed here');
 }
 
 sub Validate {
@@ -16,38 +28,46 @@
     
     my @errors;
     
-    my %nodes = map {
-        $_->nodeName ,
-        {Schema => $_, Min => $_->minOccur, Max => $_->maxOccur, Seen => 0 }
-    } @{$this->childNodes};
+    my %nodes;
+    my $anyNode;
+    foreach (@{$this->childNodes}) {
+        if ($_->isa('IMPL::DOM::Schema::AnyNode')) {
+            $anyNode = {Schema => $_, Min => $_->minOccur, Max => $_->maxOccur eq 'unbounded' ? undef : $_->maxOccur , Seen => 0 };
+        } else {
+            $nodes{$_->nodeName} = {Schema => $_, Min => $_->minOccur, Max => $_->maxOccur eq 'unbounded' ? undef : $_->maxOccur , Seen => 0 };
+        }
+    }
     
     foreach my $child ( @{$node->childNodes} ) {
-        if (my $info = $nodes{$child->nodeName}) {
+        if (my $info = $nodes{$child->nodeName} || $anyNode) {
             $info->{Seen}++;
-            push @errors,{
-                Error => 1,
+            push @errors,new IMPL::DOM::Schema::VaidationError (
                 Source => $this,
                 Node => $child,
-                Message => $this->MaxMessage
-            } if ($info->{Seen} > $info->{Max});
+                Schema => $info->{Schema},
+                Message => $this->messageMax
+            ) if ($info->{Max} and $info->{Seen} > $info->{Max});
             
-            push @errors,$info->{Schema}->Validate($child);
+            if (my @localErrors = $info->{Schema}->Validate($child)) {
+                push @errors,@localErrors;
+            }
         } else {
-            push @errors, {
-                Error => 1,
+            push @errors, new IMPL::DOM::Schema::VaidationError (
                 Source => $this,
                 Node => $child,
-                Message => $this->UnexpectedMessage
-            }
+                Schema => $info->{Schema},
+                Message => $this->messageUnexpected
+            )
         }
     }
     
     foreach my $info (values %nodes) {
-        push @errors, {
-            Error => 1,
+        push @errors, new IMPL::DOM::Schema::VaidationError (
             Source => $this,
-            Message => $this->MinMessage
-        } if $info->{Min} > $info->{Seen};
+            Schema => $info->{Schema},
+            Node => $node,
+            Message => $this->messageMin
+        ) if $info->{Min} > $info->{Seen};
     }
     
     return @errors;