8
|
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 |