XML-Compile
view release on metacpan or search on metacpan
lib/XML/Compile/Translate.pm view on Meta::CPAN
if($base !~ m/\banyType$/)
{ my $typename = $self->rel2abs($where, $node, $base);
if($type = $self->blocked($where, complexType => $typename))
{ # blocked base type
}
else
{ my $typedef = $self->namespaces->find(complexType => $typename)
or error __x"unknown base type '{type}' at {where}"
, type => $typename, where => $tree->path, _class => 'schema';
local $self->{_context} = $self->nsContext($typedef);
$type = $self->complexType($tree->descend($typedef->{node}));
}
}
my $own = $self->complexBody($tree, $mixed);
$self->extendAttrs($type, $own);
if($name eq 'extension')
{ push @{$type->{elems}}, @{$own->{elems} || []};
}
else # restriction
{ $type->{elems} = $own->{elems};
}
$type->{mixed} ||= $own->{mixed};
$type;
}
#
# Helper routines
#
# print $self->rel2abs($path, $node, '{ns}type') -> '{ns}type'
# print $self->rel2abs($path, $node, 'prefix:type') -> '{ns-of-prefix}type'
sub rel2abs($$$)
{ my ($self, $where, $node, $type) = @_;
return $type if substr($type, 0, 1) eq '{';
my ($prefix, $local) = $type =~ m/^(.+?)\:(.*)/ ? ($1, $2) : ('', $type);
my $uri = $node->lookupNamespaceURI($prefix);
$self->_registerNSprefix($prefix, $uri, 0) if $uri;
error __x"No namespace for prefix `{prefix}' in `{type}' at {where}"
, prefix => $prefix, type => $type, where => $where, _class => 'schema'
if length $prefix && !defined $uri;
pack_type $uri, $local;
}
sub _registerNSprefix($$$)
{ my ($self, $prefix, $uri, $used) = @_;
my $table = $self->{prefixes};
if(my $u = $table->{$uri}) # namespace already has a prefix
{ $u->{used} += $used;
return $u->{prefix};
}
my %prefs = map +($_->{prefix} => 1), values %$table;
my $take;
if(defined $prefix && !$prefs{$prefix}) { $take = $prefix }
elsif(!$prefs{''}) { $take = '' }
else
{ # prefix already in use; create a new x\d+ prefix
my $count = 0;
$count++ while exists $prefs{"x$count"};
$take = 'x'.$count;
}
$table->{$uri} = {prefix => $take, uri => $uri, used => $used};
$take;
}
sub anyType($)
{ my ($self, $node) = @_;
pack_type $node->namespaceURI, 'anyType';
}
sub findHooks($$$)
{ my ($self, $path, $type, $node) = @_;
# where is before, replace, after
my %hooks;
foreach my $hook (@{$self->{hooks}})
{ my $match;
$match++
if !$hook->{path} && !$hook->{id}
&& !$hook->{type} && !$hook->{extends};
if(!$match && $hook->{path})
{ my $p = $hook->{path};
$match++
if first {ref $_ eq 'Regexp' ? $path =~ $_ : $path eq $_}
ref $p eq 'ARRAY' ? @$p : $p;
}
my $id = !$match && $hook->{id} && $node->getAttribute('id');
if($id)
{ my $i = $hook->{id};
$match++
if first {ref $_ eq 'Regexp' ? $id =~ $_ : $id eq $_}
ref $i eq 'ARRAY' ? @$i : $i;
}
if(!$match && defined $type && $hook->{type})
{ my $t = $hook->{type};
my ($ns, $local) = unpack_type $type;
$match++
if first {ref $_ eq 'Regexp' ? $type =~ $_
: substr($_,0,1) eq '{' ? $type eq $_
: $local eq $_
} ref $t eq 'ARRAY' ? @$t : $t;
}
if(!$match && defined $type && $hook->{extends})
{ $match++ if $self->{nss}->doesExtend($type, $hook->{extends});
}
$match or next;
foreach my $where ( qw/before replace after/ )
{ my $w = $hook->{$where} or next;
push @{$hooks{$where}}, ref $w eq 'ARRAY' ? @$w : $w;
}
}
( run in 1.246 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )