![]() |
![]() |
use XML::Schema::Type::Complex; my $complex = XML::Schema::Type::Complex->new( name => 'MyComplexType', attributes => { attr1 => { name => 'attr1', type => $type_obj, default => $value, # 'default' or 'fixed' optional }, attr2 => { type => $type_obj }, # no default, implicit name attr3 => $type_obj, # short form of above attr4 => $attr_obj, # XML::Schema::Attribute object } content => [ ... ], # and more... ); # add new attribute my $string = XML::Schema::Type::string->new(); my $attrib = XML::Schema::Attribute->new( name => 'foo, type => $string ); # add attribute object $complex->attribute($attrib); # calls $attrib->name() to get 'foo' # fetch attribute object my $acopy = $complex->attribute('foo'); # add attribute by values $complex->attribute( name => 'bar', type => $string );
attribute( $name )
attribute( $attr_obj )
attribute( name => $name, type => $type, ... )
This method can be used to define and subsequently retrieve attribute definitions for the complex type.
When called with a single non-reference
argument, $name
, the attribute corresponding to
that name is returned. If there is no attribute defined with that
name then undef
is returned and an appropriate error message
of the form "no such attribute: $name"
is set
internally for subsequent access via the error()
method.
my $attr = $complex->attribute('lang') || die $complex->error();
In all other cases, the arguments passed are used to create
and/or define a new attribute for the complex type. If a
single argument is passed which is already a reference to an
XML::Schema::Attribute object (or appropriate
subclass or substitution class - see
XML::Schema::Factory) then its name()
method is
called and a reference to the object is stored internally
against that name as an attribute for the complex type.
my $attr = XML::Schema::Attribute->new( name => 'lang', type => 'language' ); $complex->attribute($attr);
If a single argument is passed which is a reference to a hash
array then the values contained therein will be used to create
a new attribute
object which will be assigned to the complex type as above.
The hash array should contain name
and
type
elements as a minimum.
$complex->attribute({ name => 'lang', type => 'language' });
If a list of arguments are passed then they will be automatically folded into a hash reference and treated as above.
$complex->attribute( name => 'lang', type => 'language' );
Attributes may define their type
value in terms
of a reference to a type object or a
string indicating the name of a builtin simple type
or one previously defined within the scope of the current
complex type via the simpleType()
method.
The attribute()
method calls the
scope()
on
each attribute it adopts or adds the scope
item to the hash reference used to create an attribute,
as appropriate. In either case, the effect is to bind the
attribute to the scope of the current complex type ($self
)
so that it can resolve type names to real type objects when
an instance document is parsed.
The Good Thing about this is that you can generally define
types by their names and leave the objects to worry about
resolving them to type objects at the right time. The Bad
Thing about this is that you can't define an attribute once
and then use it in a dozen different places because it's
scope
item will get overwritten each time
you assign it to a complex type. However, all is not lost
because W3C XML Schema defines Attribute Groups which are
"Write Once, Reuse Many" attributes that Do The Right Thing
to bind themselves to a scope as necessary. We'll be
supporting something like that Real Soon Now.