changeset 8:fffb153be599

DOM Schema
author Sergey
date Tue, 25 Aug 2009 17:36:37 +0400
parents 94d47b388442
children 5899df8c289e
files Lib/IMPL/DOM/Schema/ComplexNode.pm Lib/IMPL/DOM/Schema/NodeList.pm Lib/IMPL/DOM/Schema/SimpleNode.pm
diffstat 3 files changed, 90 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/Lib/IMPL/DOM/Schema/ComplexNode.pm	Mon Aug 24 01:05:34 2009 +0400
+++ b/Lib/IMPL/DOM/Schema/ComplexNode.pm	Tue Aug 25 17:36:37 2009 +0400
@@ -33,15 +33,7 @@
         my @errors;
         push @errors, $_->Validate foreach @{$this->childNodes};
         
-        if (@errors and $this->Message) {
-            return {
-                Error => 1,
-                Message => $this->formatMessage($node),
-                InnerErrors => \@errors
-            };
-        } else {
-            return @errors;
-        }
+        return @errors;
     }
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Lib/IMPL/DOM/Schema/NodeList.pm	Tue Aug 25 17:36:37 2009 +0400
@@ -0,0 +1,83 @@
+package IMPL::DOM::Schema::NodeList;
+use strict;
+use warnings;
+use base qw(IMPL::DOM::Schema::Item);
+use IMPL::Class::Property;
+
+BEGIN {
+    public property MessageUnexpected => prop_all;
+    public property MessageNodesRequired => prop_all;
+}
+
+sub Validate {
+    my ($this,$node) = @_;
+    
+    my @nodes = map {
+        {nodeName => $_->nodeName, Schema => $_, Min => $_->minOccur, Max => $_->maxOccur, Seen => 0 }
+    } @{$this->childNodes};
+    
+    my $info = shift @nodes;
+    
+    foreach my $child ( @{$node->childNodes} ) {
+        #skip schema elements
+        while ($info and $info->{nodeName} ne $child->nodeName) {
+            # if possible of course :)
+            return {
+                Error => 1,
+                Message => $this->MessageUnexpected,
+                Node => $child,
+                Source => $this
+            } if $info->{Min} > $info->{Seen};
+            
+            $info = shift @nodes;
+        }
+        
+        # return error if no more children allowed
+        return {
+            Error => 1,
+            Message => $this->MessageUnexpected,
+            Node => $child,
+            Source => $this
+        } unless $info;
+        
+        # it's ok, we found schema element for him
+        $info->{Seen}++;
+        
+        # check count limits
+        return {
+            Error => 1,
+            Message => $this->MessageUnexpected,
+            Node => $child,
+            Source => $this,
+        } if $info->{Seen} > $info->{Max};
+        
+        # validate
+        if (my @errors = $info->{Schema}->Validate($child)) {
+            return @errors;
+        }
+    }
+    
+    # no more children left (but may be should :)
+    while ($info) {
+        return {
+            Error => 1,
+            Message => $this->MessageNodesRequired,
+            Source => $this
+        } if $info->{Seen} < $info->{Min};
+        
+        $info = shift @nodes;
+    }
+}
+
+1;
+
+__END__
+
+=pod
+
+=head1 DESCRIPTION
+
+Содержимое для сложного узла. Порядок важен. Дочерними элементами могут быть
+только C<IMPL::DOM::Schema::ComplexNode> и C<IMPL::DOM::Schema::SimpleNode>.
+
+=cut
\ No newline at end of file
--- a/Lib/IMPL/DOM/Schema/SimpleNode.pm	Mon Aug 24 01:05:34 2009 +0400
+++ b/Lib/IMPL/DOM/Schema/SimpleNode.pm	Tue Aug 25 17:36:37 2009 +0400
@@ -6,6 +6,12 @@
 
 __PACKAGE__->PassThroughArgs;
 
+sub Validate {
+    my ($this,$node) = @_;
+    
+    map $_->Validate($node), @{$this->childNodes};    
+}
+
 1;
 
 __END__