comparison Lib/IMPL/DOM/Schema/NodeList.pm @ 8:fffb153be599

DOM Schema
author Sergey
date Tue, 25 Aug 2009 17:36:37 +0400
parents
children 1ca530e5c9c5
comparison
equal deleted inserted replaced
7:94d47b388442 8:fffb153be599
1 package IMPL::DOM::Schema::NodeList;
2 use strict;
3 use warnings;
4 use base qw(IMPL::DOM::Schema::Item);
5 use IMPL::Class::Property;
6
7 BEGIN {
8 public property MessageUnexpected => prop_all;
9 public property MessageNodesRequired => prop_all;
10 }
11
12 sub Validate {
13 my ($this,$node) = @_;
14
15 my @nodes = map {
16 {nodeName => $_->nodeName, Schema => $_, Min => $_->minOccur, Max => $_->maxOccur, Seen => 0 }
17 } @{$this->childNodes};
18
19 my $info = shift @nodes;
20
21 foreach my $child ( @{$node->childNodes} ) {
22 #skip schema elements
23 while ($info and $info->{nodeName} ne $child->nodeName) {
24 # if possible of course :)
25 return {
26 Error => 1,
27 Message => $this->MessageUnexpected,
28 Node => $child,
29 Source => $this
30 } if $info->{Min} > $info->{Seen};
31
32 $info = shift @nodes;
33 }
34
35 # return error if no more children allowed
36 return {
37 Error => 1,
38 Message => $this->MessageUnexpected,
39 Node => $child,
40 Source => $this
41 } unless $info;
42
43 # it's ok, we found schema element for him
44 $info->{Seen}++;
45
46 # check count limits
47 return {
48 Error => 1,
49 Message => $this->MessageUnexpected,
50 Node => $child,
51 Source => $this,
52 } if $info->{Seen} > $info->{Max};
53
54 # validate
55 if (my @errors = $info->{Schema}->Validate($child)) {
56 return @errors;
57 }
58 }
59
60 # no more children left (but may be should :)
61 while ($info) {
62 return {
63 Error => 1,
64 Message => $this->MessageNodesRequired,
65 Source => $this
66 } if $info->{Seen} < $info->{Min};
67
68 $info = shift @nodes;
69 }
70 }
71
72 1;
73
74 __END__
75
76 =pod
77
78 =head1 DESCRIPTION
79
80 Содержимое для сложного узла. Порядок важен. Дочерними элементами могут быть
81 только C<IMPL::DOM::Schema::ComplexNode> и C<IMPL::DOM::Schema::SimpleNode>.
82
83 =cut