Mercurial > pub > Impl
view Lib/IMPL/DOM/Schema.pm @ 22:da5bc24b3d3c
wmi tests
author | Sergey |
---|---|
date | Wed, 30 Sep 2009 17:41:32 +0400 |
parents | 267460284fb3 |
children | fafe56cfcd69 |
line wrap: on
line source
package IMPL::DOM::Schema; use strict; use warnings; require IMPL::DOM::Schema::ComplexNode; require IMPL::DOM::Schema::ComplexType; require IMPL::DOM::Schema::SimpleNode; require IMPL::DOM::Schema::SimpleType; require IMPL::DOM::Schema::Node; require IMPL::DOM::Schema::AnyNode; require IMPL::DOM::Schema::NodeList; require IMPL::DOM::Schema::NodeSet; use base qw(IMPL::DOM::Document); use IMPL::Class::Property; use IMPL::Class::Property::Direct; __PACKAGE__->PassThroughArgs; BEGIN { private _direct property _TypesMap => prop_all; } sub resolveType { $_[0]->{$_TypesMap}->{$_[1]}; } sub Process { my ($this) = @_; $this->{$_TypesMap} = { map { $_->type, $_ } grep {$_->isa('IMPL::DOM::Schema::Type')} @{$this->childNodes} }; } sub Validate { my ($this,$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; sub MetaSchema { return $schema if $schema; $schema = new IMPL::DOM::Schema(nodeName => 'schema'); $schema->appendRange( IMPL::DOM::Schema::ComplexNode->new(name => 'schema')->appendRange( IMPL::DOM::Schema::NodeSet->new()->appendRange( 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(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(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(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(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( IMPL::DOM::Schema::NodeSet->new()->appendRange( IMPL::DOM::Schema::AnyNode->new(maxOccur => 'unbounded', minOccur => 0) ) ), IMPL::DOM::Schema::ComplexType->new(type => 'SimpleNode', nativeType => 'IMPL::DOM::Schema::SimpleNode')->appendRange( IMPL::DOM::Schema::NodeSet->new()->appendRange( IMPL::DOM::Schema::AnyNode->new(maxOccur => 'unbounded', minOccur => 0) ) ) ); $schema->Process; return $schema; } 1; __END__ =pod =head1 DESCRIPTION Схема документа. Наследует C<IMPL::DOM::Document> =head1 METHODS =over =item C<< $obj->Process() >> Обновляет таблицу типов из содержимого. =item C<< $obj->ResolveType($typeName) >> Возвращает схему типа c именем C<$typeName>. =back =head1 DESCRIPTION DOM схема - это документ, состоящий из определенных узлов, описывающая структуру других документов. =head1 META SCHEMA Схема для описания схемы, эта схема используется для постороения других схем <schema> <ComplexNode name="schema"> <NodeSet> <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" 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 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 name="NodeSet" type="NodeContainer" minOcuur=0/> <Node name="NodeList" type="NodeContainer" minOccur=0/> <AnyNode minOccur="0" maxOccur="unbounded"/> </NodeList> </ComplexType> <ComplexType type="SimpleNode"> <NodeSet> <AnyNode minOccur=0 maxOccur="unbounded"/> </NodeSet> </ComplexType> <ComplexType type="SimpleType"> <NodeSet> <AnyNode minOccur=0 maxOccur="unbounded"/> </NodeSet> </ComplexType> </schema> =cut