[
Lists Home |
Date Index |
Thread Index
]
Joe Chiusano wrote:
> W3C Schema contains a feature called Abstract Datatypes that I
> believe may be useful to you. In a nutshell, abstract datatypes are
> complex datatypes that act as "templates" from which other complex
> datatypes are derived. However, unlike base datatypes, abstract
> datatypes cannot be used directly in element declaration (i.e. you
> can declare an element to be of a type that is derived from the
> abstract datatype, but not of the abstract datatype itself).
Just to clarify, you *can* declare an element to be of an abstract
type (an element declaration can have a type that is an abstract type)
but it's not legal for an element in the instance to be validated
against that type. If you declare an element to be of an abstract type
then all the instances of that element must use xsi:type to indicate
their actual, concrete type.
In fact, this is one way of managing co-occurrence constraints when
you're using W3C XML Schema. Declare an abstract type that covers
everything:
<xs:complexType name="_hopType" abstract="true">
<xs:group ref="hopContent" />
<xs:attribute name="skip" type="xs:anyURI" />
<xs:attribute name="jump" type="xs:anyURI" />
</xs:complexType>
from which you derive the concrete types for the two (or more) options
that you want to allow:
<xs:complexType name="skipType">
<xs:restriction base="_hopType">
<xs:attribute name="skip" use="required" />
<xs:attribute name="jump" use="prohibited" />
</xs:restriction>
</xs:complexType>
<xs:complexType name="jumpType">
<xs:restriction base="_hopType">
<xs:attribute name="skip" use="prohibited" />
<xs:attribute name="jump" use="required" />
</xs:restriction>
</xs:complexType>
and declare the element to be of the abstract type:
<xs:element name="hop" type="_hopType" />
This forces the author of the instance document to use xsi:type to
specify which of the two kinds of hops they're talking about. These
are legal:
<hop xsi:type="skipType" skip="file.xml">...</hop>
<hop xsi:type="jumpType" jump="file.xml">...</hop>
but these aren't:
<hop xsi:type="skipType" jump="file.xml">...</hop>
<hop xsi:type="jumpType" skip="file.xml">...</hop>
<hop skip="file.xml">...</hop>
<hop jump="file.xml">...</hop>
<hop skip="file.xml" jump="file.xml">...</hop>
In Tom's case:
Tom Maciejewski wrote:
> Is there a way to enforce abstract types. For example lets say I
> have an interface : printable
>
> but then I have a concrete "class" wordDocument that derives from
> printable with some additional information. Lets say I would like to
> serialize these objects to XML. Lets say I also have a class queue
> that can have many "printable" objects ...
>
> so in my xml I would like to have :
>
> <foo>
> <wordDocument name="toms document" />
> <excelDocument name="toms spreadsheet" />
> </foo>
>
> but not allow:
> <foo>
> <printable />
> </foo>
>
> we may assume that there actually is more data in these elements
it's probably a good idea to use substitution groups with abstract
elements:
<xs:element name="printable" abstract="true" type="printableType" />
<xs:element name="wordDocument" substitutionGroup="printable" />
<xs:element name="excelDocument" substitutionGroup="printable" />
<xs:element name="foo">
<xs:complexType>
<xs:sequence>
<xs:element ref="printable" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
Because the printable element is abstract, it can't actually appear in
an instance. However, the wordDocument and excelDocument elements can
appear in its place. By default, these elements will adopt printable's
type as well, although they can be declared with their own types as
long as they're derived (by extension or restriction) from printable's
type.
Note, though, that printable here is more like a class than an
interface -- an element can only be a member of one substitution
group, so you can't say that a wordDocument element is both printable
and editable, for example.
Cheers,
Jeni
---
Jeni Tennison
http://www.jenitennison.com/
|