changeset 20:267460284fb3

DOM Schema
author Sergey
date Tue, 22 Sep 2009 17:17:38 +0400
parents 1ca530e5c9c5
children fafe56cfcd69 da5bc24b3d3c
files Lib/IMPL/DOM/Schema.pm Lib/IMPL/DOM/Schema/AnyNode.pm Lib/IMPL/DOM/Schema/ComplexNode.pm Lib/IMPL/DOM/Schema/ComplexType.pm Lib/IMPL/DOM/Schema/Node.pm Lib/IMPL/DOM/Schema/NodeList.pm Lib/IMPL/DOM/Schema/NodeSet.pm Lib/IMPL/DOM/Schema/SimpleNode.pm Lib/IMPL/DOM/Schema/SimpleType.pm impl.kpf
diffstat 10 files changed, 119 insertions(+), 46 deletions(-) [+]
line wrap: on
line diff
--- a/Lib/IMPL/DOM/Schema.pm	Fri Sep 11 16:30:39 2009 +0400
+++ b/Lib/IMPL/DOM/Schema.pm	Tue Sep 22 17:17:38 2009 +0400
@@ -34,7 +34,11 @@
 sub Validate {
     my ($this,$node) = @_;
     
-    #return IMPL::DOM::Schema::NodeSet->new()->appendRange(@{$this->childNodes})->Validate($node);
+    if ( my ($schemaNode) = $this->selectNodes(sub { $_[0]->name eq $node->nodeName })) {
+        $schemaNode->Validate($node);
+    } else {
+        return IMPL::DOM::Schema::VaidationError(Message=> "A specified document doesn't match the schema");
+    }
 }
 
 my $schema;
@@ -46,42 +50,42 @@
     $schema = new IMPL::DOM::Schema(nodeName => 'schema');
     
     $schema->appendRange(
-        IMPL::DOM::Schema::ComplexNode->new(nodeName => 'schema')->appendRange(
+        IMPL::DOM::Schema::ComplexNode->new(name => 'schema')->appendRange(
             IMPL::DOM::Schema::NodeSet->new()->appendRange(
-                IMPL::DOM::Schema::Node->new(nodeName => 'ComplexNode', type => 'ComplexNode', minOccur => 0, maxOccur=>'unbounded'),
-                IMPL::DOM::Schema::Node->new(nodeName => 'ComplexType', type => 'ComplexType', minOccur => 0, maxOccur=>'unbounded'),
-                IMPL::DOM::Schema::Node->new(nodeName => 'SimpleNode', type => 'SimpleNode', minOccur => 0, maxOccur=>'unbounded'),
-                IMPL::DOM::Schema::Node->new(nodeName => 'SimpleType', type => 'SimpleType', minOccur => 0, maxOccur=>'unbounded'),
-                IMPL::DOM::Schema::SimpleNode->new(nodeName => 'Node', minOccur => 0, maxOccur=>'unbounded'),
-                IMPL::DOM::Schema::SimpleNode->new(nodeName => 'Include', minOccur => 0, maxOccur=>'unbounded')
+                IMPL::DOM::Schema::Node->new(name => 'ComplexNode', type => 'ComplexNode', minOccur => 0, maxOccur=>'unbounded'),
+                IMPL::DOM::Schema::Node->new(name => 'ComplexType', type => 'ComplexType', minOccur => 0, maxOccur=>'unbounded'),
+                IMPL::DOM::Schema::Node->new(name => 'SimpleNode', type => 'SimpleNode', minOccur => 0, maxOccur=>'unbounded'),
+                IMPL::DOM::Schema::Node->new(name => 'SimpleType', type => 'SimpleType', minOccur => 0, maxOccur=>'unbounded'),
+                IMPL::DOM::Schema::SimpleNode->new(name => 'Node', minOccur => 0, maxOccur=>'unbounded'),
+                IMPL::DOM::Schema::SimpleNode->new(name => 'Include', minOccur => 0, maxOccur=>'unbounded')
             ),
         ),
         IMPL::DOM::Schema::ComplexType->new(type => 'NodeSet', nativeType => 'IMPL::DOM::Schema::NodeSet')->appendRange(
             IMPL::DOM::Schema::NodeSet->new()->appendRange(
-                IMPL::DOM::Schema::Node->new(nodeName => 'ComplexNode', type => 'ComplexNode', minOccur => 0, maxOccur=>'unbounded'),
-                IMPL::DOM::Schema::Node->new(nodeName => 'SimpleNode', type => 'SimpleNode', minOccur => 0, maxOccur=>'unbounded'),
-                IMPL::DOM::Schema::SimpleNode->new(nodeName => 'Node', minOccur => 0, maxOccur=>'unbounded'),
+                IMPL::DOM::Schema::Node->new(name => 'ComplexNode', type => 'ComplexNode', minOccur => 0, maxOccur=>'unbounded'),
+                IMPL::DOM::Schema::Node->new(name => 'SimpleNode', type => 'SimpleNode', minOccur => 0, maxOccur=>'unbounded'),
+                IMPL::DOM::Schema::SimpleNode->new(name => 'Node', minOccur => 0, maxOccur=>'unbounded'),
             )
         ),
         IMPL::DOM::Schema::ComplexType->new(type => 'NodeList', nativeType => 'IMPL::DOM::Schema::NodeList')->appendRange(
             IMPL::DOM::Schema::NodeSet->new()->appendRange(
-                IMPL::DOM::Schema::Node->new(nodeName => 'ComplexNode', type => 'ComplexNode', minOccur => 0, maxOccur=>'unbounded'),
-                IMPL::DOM::Schema::Node->new(nodeName => 'SimpleNode', type => 'SimpleNode', minOccur => 0, maxOccur=>'unbounded'),
-                IMPL::DOM::Schema::SimpleNode->new(nodeName => 'Node', minOccur => 0, maxOccur=>'unbounded'),
+                IMPL::DOM::Schema::Node->new(name => 'ComplexNode', type => 'ComplexNode', minOccur => 0, maxOccur=>'unbounded'),
+                IMPL::DOM::Schema::Node->new(name => 'SimpleNode', type => 'SimpleNode', minOccur => 0, maxOccur=>'unbounded'),
+                IMPL::DOM::Schema::SimpleNode->new(name => 'Node', minOccur => 0, maxOccur=>'unbounded'),
             )
         ),
         IMPL::DOM::Schema::ComplexType->new(type => 'ComplexType', nativeType => 'IMPL::DOM::Schema::ComplexType')->appendRange(
             IMPL::DOM::Schema::NodeList->new()->appendRange(
-                IMPL::DOM::Schema::Node->new(nodeName => 'NodeSet', minOccur => 0, type => 'NodeSet'),
-                IMPL::DOM::Schema::Node->new(nodeName => 'NodeList', minOccur => 0, type => 'NodeSet'),
-                IMPL::DOM::Schema::SimpleNode->new(nodeName => 'Node', minOccur => 0, maxOccur => 'unbounded')
+                IMPL::DOM::Schema::Node->new(name => 'NodeSet', minOccur => 0, type => 'NodeSet'),
+                IMPL::DOM::Schema::Node->new(name => 'NodeList', minOccur => 0, type => 'NodeSet'),
+                IMPL::DOM::Schema::SimpleNode->new(name => 'Node', minOccur => 0, maxOccur => 'unbounded')
             )
         ),
         IMPL::DOM::Schema::ComplexType->new(type => 'ComplexNode', nativeType => 'IMPL::DOM::Schema::ComplexNode')->appendRange(
             IMPL::DOM::Schema::NodeList->new()->appendRange(
-                IMPL::DOM::Schema::Node->new(nodeName => 'NodeSet', minOccur => 0, type => 'NodeSet'),
-                IMPL::DOM::Schema::Node->new(nodeName => 'NodeList', minOccur => 0, type => 'NodeSet'),
-                IMPL::DOM::Schema::SimpleNode->new(nodeName => 'Node', minOccur => 0, maxOccur => 'unbounded')
+                IMPL::DOM::Schema::Node->new(name => 'NodeSet', minOccur => 0, type => 'NodeSet'),
+                IMPL::DOM::Schema::Node->new(name => 'NodeList', minOccur => 0, type => 'NodeSet'),
+                IMPL::DOM::Schema::SimpleNode->new(name => 'Node', minOccur => 0, maxOccur => 'unbounded')
             )
         ),
         IMPL::DOM::Schema::ComplexType->new(type => 'SimpleType', nativeType => 'IMPL::DOM::Schema::SimpleType')->appendRange(
@@ -125,43 +129,48 @@
 
 =back
 
+=head1 DESCRIPTION
+
+DOM схема - это документ, состоящий из определенных узлов, описывающая структуру
+других документов.
+
 =head1 META SCHEMA
 
 Схема для описания схемы, эта схема используется для постороения других схем
 
 <schema>
-    <ComplexNode nodeName="schema">
+    <ComplexNode name="schema">
         <NodeSet>
-            <Node minOcuur="0" maxOccur="unbounded" nodeName="ComplexNode" type="ComplexNode"/>
-            <Node minOcuur="0" maxOccur="unbounded" nodeName="SimpleNode" type="SimpleNode"/>
-            <Node minOcuur="0" maxOccur="unbounded" nodeName="ComplexType" type="ComplexType"/>
-            <Node minOcuur="0" maxOccur="unbounded" nodeName="SimpleType" type="SimpleType"/>
-            <SimpleNode minOcuur="0" maxOccur="unbounded" nodeName="Node"/>
-            <SimpleNode minOcuur="0" maxOccur="unbounded" nodeName="Include"/>
+            <Node minOcuur="0" maxOccur="unbounded" name="ComplexNode" type="ComplexNode"/>
+            <Node minOcuur="0" maxOccur="unbounded" name="SimpleNode" type="SimpleNode"/>
+            <Node minOcuur="0" maxOccur="unbounded" name="ComplexType" type="ComplexType"/>
+            <Node minOcuur="0" maxOccur="unbounded" name="SimpleType" type="SimpleType"/>
+            <SimpleNode minOcuur="0" maxOccur="unbounded" name="Node"/>
+            <SimpleNode minOcuur="0" maxOccur="unbounded" name="Include"/>
         </NodeSet>
     </ComplexNode>
     
     <ComplexType type="NodeContainer">
         <NodeSet>
-            <Node minOcuur="0" maxOccur="unbounded" nodeName="ComplexNode" type="ComplexNode"/>
-            <Node minOcuur="0" maxOccur="unbounded" nodeName="SimpleNode" type="SimpleNode"/>
-            <SimpleNode minOcuur="0" maxOccur="unbounded" nodeName="Node"/>
+            <Node minOcuur="0" maxOccur="unbounded" name="ComplexNode" type="ComplexNode"/>
+            <Node minOcuur="0" maxOccur="unbounded" name="SimpleNode" type="SimpleNode"/>
+            <SimpleNode minOcuur="0" maxOccur="unbounded" name="Node"/>
         </NodeSet>
     </ComplexType>
     
     
     <ComplexType type="ComplexType">
         <NodeList>
-            <Node nodeName="NodeSet" type="NodeContainer" minOcuur=0/>
-            <Node nodeName="NodeList" type="NodeContainer" minOccur=0/>
+            <Node name="NodeSet" type="NodeContainer" minOcuur=0/>
+            <Node name="NodeList" type="NodeContainer" minOccur=0/>
             <AnyNode minOccur="0" maxOccur="unbounded"/>
         </NodeList>
     </ComplexType>
     
     <ComplexType type="ComplexNode">
         <NodeList>
-            <Node nodeName="NodeSet" type="NodeContainer" minOcuur=0/>
-            <Node nodeName="NodeList" type="NodeContainer" minOccur=0/>
+            <Node name="NodeSet" type="NodeContainer" minOcuur=0/>
+            <Node name="NodeList" type="NodeContainer" minOccur=0/>
             <AnyNode minOccur="0" maxOccur="unbounded"/>
         </NodeList>
     </ComplexType>
--- a/Lib/IMPL/DOM/Schema/AnyNode.pm	Fri Sep 11 16:30:39 2009 +0400
+++ b/Lib/IMPL/DOM/Schema/AnyNode.pm	Tue Sep 22 17:17:38 2009 +0400
@@ -5,7 +5,7 @@
 use base qw(IMPL::DOM::Schema::Node);
 
 our %CTOR = (
-    'IMPL::DOM::Schema::Node' => sub { nodeName => 'AnyNode'}
+    'IMPL::DOM::Schema::Node' => sub { nodeName => 'AnyNode', name=> 'AnyNode'}
 );
 
 1;
--- a/Lib/IMPL/DOM/Schema/ComplexNode.pm	Fri Sep 11 16:30:39 2009 +0400
+++ b/Lib/IMPL/DOM/Schema/ComplexNode.pm	Tue Sep 22 17:17:38 2009 +0400
@@ -12,7 +12,9 @@
     }
 }
 
-__PACKAGE__->PassThroughArgs;
+our %CTOR = (
+    'IMPL::DOM::Schema::Node' => sub {my %args = @_; $args{nodeName} ||= 'ComplexNode'; %args }
+);
 
 sub _getContent {
     $_[0]->firstChild;
--- a/Lib/IMPL/DOM/Schema/ComplexType.pm	Fri Sep 11 16:30:39 2009 +0400
+++ b/Lib/IMPL/DOM/Schema/ComplexType.pm	Tue Sep 22 17:17:38 2009 +0400
@@ -13,9 +13,10 @@
 our %CTOR = (
     'IMPL::DOM::Schema::ComplexNode' => sub {
         my %args = @_;
-        $args{nodeName} = 'ComplexNode';
+        $args{nodeName} ||= 'ComplexType';
         $args{minOccur} = 0;
         $args{maxOccur} = 'unbounded';
+        $args{name} ||= 'ComplexType';
         %args
     }
 );
--- a/Lib/IMPL/DOM/Schema/Node.pm	Fri Sep 11 16:30:39 2009 +0400
+++ b/Lib/IMPL/DOM/Schema/Node.pm	Tue Sep 22 17:17:38 2009 +0400
@@ -10,17 +10,21 @@
 BEGIN {
     public property minOccur => prop_all;
     public property maxOccur => prop_all;
-    public property type => prop_all
+    public property type => prop_all;
+    public property name => prop_all;
 }
 
-__PACKAGE__->PassThroughArgs;
+our %CTOR = (
+    'IMPL::DOM::Node' => sub {my %args = @_; $args{nodeName} ||= 'Node'; %args}
+);
 
 sub CTOR {
     my ($this,%args) = @_;
     
-    $this->minOccur(defined $args{minOcuur} ? $args{minOcuur} : 1);
+    $this->minOccur(defined $args{minOccur} ? $args{minOccur} : 1);
     $this->maxOccur(defined $args{maxOccur} ? $args{maxOccur} : 1);
     $this->type($args{type});
+    $this->name($args{name}) or die new IMPL::InvalidArgumentException('Argument is required','name');
 }
 
 sub Validate {
@@ -28,6 +32,8 @@
     
     if (my $schemaType = $this->type ? $this->rootNode->resolveType($this->type) : undef ) {
         return $schemaType->Validate($node);
+    } else {
+        return ();
     }
 }
 
@@ -47,6 +53,6 @@
 
 =head1 DESCRIPTION
 
-Базовый класс для элементов схемы. Содержит в себе базовые методы 
+Базовый класс для элементов схемы.
 
 =cut
--- a/Lib/IMPL/DOM/Schema/NodeList.pm	Fri Sep 11 16:30:39 2009 +0400
+++ b/Lib/IMPL/DOM/Schema/NodeList.pm	Tue Sep 22 17:17:38 2009 +0400
@@ -26,7 +26,7 @@
     my ($this,$node) = @_;
     
     my @nodes = map {
-        {nodeName => $_->nodeName, anyNode => $_->isa('IMPL::DOM::Schema::AnyNode') , Schema => $_, Min => $_->minOccur eq 'unbounded' ? undef : $_->maxOccur, Max => $_->maxOccur, Seen => 0 }
+        {nodeName => $_->name, anyNode => $_->isa('IMPL::DOM::Schema::AnyNode') , Schema => $_, Min => $_->minOccur eq 'unbounded' ? undef : $_->maxOccur, Max => $_->maxOccur, Seen => 0 }
     } @{$this->childNodes};
     
     my $info = shift @nodes;
--- a/Lib/IMPL/DOM/Schema/NodeSet.pm	Fri Sep 11 16:30:39 2009 +0400
+++ b/Lib/IMPL/DOM/Schema/NodeSet.pm	Tue Sep 22 17:17:38 2009 +0400
@@ -19,7 +19,7 @@
     my ($this,%args) = @_;
     
     $this->messageMax( $args{messageMax} || 'Too many %Node.nodeName% nodes');
-    $this->messageMin( $args{messageMin} || '%Schema.nodeName% nodes expected');
+    $this->messageMin( $args{messageMin} || '%Schema.name% nodes expected');
     $this->messageUnexpected( $args{messageUnexpected} || 'A %Node.nodeName% isn\'t allowed here');
 }
 
@@ -34,7 +34,7 @@
         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 };
+            $nodes{$_->name} = {Schema => $_, Min => $_->minOccur, Max => $_->maxOccur eq 'unbounded' ? undef : $_->maxOccur , Seen => 0 };
         }
     }
     
--- a/Lib/IMPL/DOM/Schema/SimpleNode.pm	Fri Sep 11 16:30:39 2009 +0400
+++ b/Lib/IMPL/DOM/Schema/SimpleNode.pm	Tue Sep 22 17:17:38 2009 +0400
@@ -4,7 +4,9 @@
 
 use base qw(IMPL::DOM::Schema::Node);
 
-__PACKAGE__->PassThroughArgs;
+our %CTOR = (
+    'IMPL::DOM::Schema::Node' => sub {my %args = @_; $args{nodeName} ||= 'SimpleNode'; %args}
+);  
 
 sub Validate {
     my ($this,$node) = @_;
--- a/Lib/IMPL/DOM/Schema/SimpleType.pm	Fri Sep 11 16:30:39 2009 +0400
+++ b/Lib/IMPL/DOM/Schema/SimpleType.pm	Tue Sep 22 17:17:38 2009 +0400
@@ -13,9 +13,10 @@
 our %CTOR = (
     'IMPL::DOM::Schema::SimpleNode' => sub {
         my %args = @_;
-        $args{nodeName} = 'ComplexNode';
+        $args{nodeName} = 'SimpleType';
         $args{minOccur} = 0;
         $args{maxOccur} = 'unbounded';
+        $args{name} ||= 'SimpleType';
         %args
     }
 );
--- a/impl.kpf	Fri Sep 11 16:30:39 2009 +0400
+++ b/impl.kpf	Tue Sep 22 17:17:38 2009 +0400
@@ -170,6 +170,32 @@
 </preference-set>
   <string id="lastInvocation">default</string>
 </preference-set>
+<preference-set idref="66c7d414-175f-45b6-92fe-dbda51c64843/Lib/IMPL/DOM/Schema/ComplexNode.pm">
+<preference-set id="Invocations">
+<preference-set id="default">
+  <string id="cookieparams"></string>
+  <string id="cwd"></string>
+  <long id="debugger.io-port">9011</long>
+  <string id="documentRoot"></string>
+  <string id="executable-params"></string>
+  <string relative="path" id="filename">Lib/IMPL/DOM/Schema/ComplexNode.pm</string>
+  <string id="getparams"></string>
+  <string id="language">Perl</string>
+  <string id="mpostparams"></string>
+  <string id="params"></string>
+  <string id="postparams"></string>
+  <string id="posttype">application/x-www-form-urlencoded</string>
+  <string id="request-method">GET</string>
+  <boolean id="show-dialog">1</boolean>
+  <boolean id="sim-cgi">0</boolean>
+  <boolean id="use-console">0</boolean>
+  <string id="userCGIEnvironment"></string>
+  <string id="userEnvironment"></string>
+  <string id="warnings">enabled</string>
+</preference-set>
+</preference-set>
+  <string id="lastInvocation">default</string>
+</preference-set>
 <preference-set idref="66c7d414-175f-45b6-92fe-dbda51c64843/Lib/IMPL/DOM/Schema/Item.pm">
 <preference-set id="Invocations">
 <preference-set id="default">
@@ -326,6 +352,32 @@
 </preference-set>
   <string id="lastInvocation">default</string>
 </preference-set>
+<preference-set idref="66c7d414-175f-45b6-92fe-dbda51c64843/_test/Test/DOM/Schema.pm">
+<preference-set id="Invocations">
+<preference-set id="default">
+  <string id="cookieparams"></string>
+  <string id="cwd"></string>
+  <long id="debugger.io-port">9011</long>
+  <string id="documentRoot"></string>
+  <string id="executable-params"></string>
+  <string relative="path" id="filename">_test/Test/DOM/Schema.pm</string>
+  <string id="getparams"></string>
+  <string id="language">Perl</string>
+  <string id="mpostparams"></string>
+  <string id="params"></string>
+  <string id="postparams"></string>
+  <string id="posttype">application/x-www-form-urlencoded</string>
+  <string id="request-method">GET</string>
+  <boolean id="show-dialog">1</boolean>
+  <boolean id="sim-cgi">0</boolean>
+  <boolean id="use-console">0</boolean>
+  <string id="userCGIEnvironment"></string>
+  <string id="userEnvironment"></string>
+  <string id="warnings">enabled</string>
+</preference-set>
+</preference-set>
+  <string id="lastInvocation">default</string>
+</preference-set>
 <preference-set idref="66c7d414-175f-45b6-92fe-dbda51c64843/_test/Web.t">
 <preference-set id="Invocations">
 <preference-set id="default">