| Previous | Next
Allowing Any ContentIt is often necessary to allow users to include any type of markup content they see fit. Also, it is useful to tell the schema processor to validate the content of a particular element against another application's schema. Incorporating XHTML content into another document is an example of this usage. These applications are supported by the <xs:element name="notes" minOccurs="0"> <xs:complexType> <xs:sequence> <xs:any namespace="http://www.w3.org/1999/xhtml" minOccurs="0" maxOccurs="unbounded" processContents="skip"/> </xs:sequence> </xs:complexType> </xs:element> The attributes of the There is also support in schemas to declare that any attribute may appear within a given element. The <xs:element name="address"> <xs:complexType> . . . <xs:attributeGroup ref="addr:nationality"/> <xs:attribute name="ssn" type="addr:ssn"/> <xs:anyAttribute namespace="http://www.w3.org/1999/xlink" processContents="skip"/> </xs:complexType> </xs:element> As an application grows and becomes more complex, it is important to take steps to maintain readability and extensibility. Things like separating a large schema into multiple documents, importing declarations from external schemas, and deriving new types from existing types are all typical tasks that will face designers of real-world schemas. Using Multiple DocumentsJust as large computer programs are separated into multiple physical source files, large schemas can be separated into smaller, self-contained schema documents. Although a single large schema could be arbitrarily separated into multiple smaller documents, taking the time to group related declarations into reusable modules can simplify future schema development. There are three mechanisms that include declarations from external schemas for use within a given schema: Including external declarationsThe Example 16-12. physical-address.xsd<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://namespaces.anonymous.com/xmlnut/address" xmlns:addr="http://namespaces.anonymous.com/xmlnut/address" attributeFormDefault="qualified" elementFormDefault="qualified"> <xs:annotation> <xs:documentation xml:lang="en-us"> Simple schema example from Anonymous's <a href="http://wikipedia.org/w/index.php?search=xmlnut">XML in a Nutshell.</a> copyleft 2002 Anonymous & Associates </xs:documentation> </xs:annotation> <xs:complexType name="physicalAddressType"> <xs:sequence> <xs:element name="street" type="xs:string" maxOccurs="3"/> <xs:element name="city" type="xs:string"/> <xs:element name="state" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:schema> The <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://namespaces.anonymous.com/xmlnut/address" xmlns:addr="http://namespaces.anonymous.com/xmlnut/address" attributeFormDefault="qualified" elementFormDefault="qualified"> . . . <xs:include schemaLocation="physical-address.xsd"/> <xs:element name="address"> <xs:complexType> <xs:sequence> . . . <xs:element name="physicalAddress" type="addr:physicalAddressType"/> . . . </xs:sequence> . . . </xs:complexType> </xs:element> Content that has been included using the Modifying external declarationsThe Functionally, the <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://namespaces.anonymous.com/xmlnut/address" xmlns:addr="http://namespaces.anonymous.com/xmlnut/address" attributeFormDefault="qualified" elementFormDefault="qualified"> . . . <xs:redefine schemaLocation="physical-address.xsd"> <xs:complexType name="physicalAddressType"> <xs:complexContent> <xs:extension base="addr:physicalAddressType"> <xs:attribute name="latitude" type="xs:decimal"/> <xs:attribute name="longitude" type="xs:decimal"/> </xs:extension> </xs:complexContent> </xs:complexType> </xs:redefine> . . . </xs:schema> Importing schemas for other namespacesThe Using To use some of the types from this library in a schema, include the following <xs:import namespace="http://www.w3.org/2001/03/XMLSchema/TypeLibrary" schemaLocation="http://www.w3.org/2001/03/XMLSchema/TypeLibrary.xsd"/> Derived Complex TypesWe have been using the Deriving by extensionWhen deriving a new type from an existing type, the resulting type is equivalent to appending the contents of the new declaration to the contents of the base declaration. For instance, the following example declares a new type called <xs:complexType name="mailingAddressType"> <xs:complexContent> <xs:extension base="addr:physicalAddressType"> <xs:sequence> <xs:element name="zipCode" type="xs:string"/> </xs:sequence> </xs:extension> </xs:complexContent> </xs:complexType> This declaration appends a required element, Deriving by restrictionWhen a new type is a logical subset of an existing type, the In the case of complex types, it is not quite so straightforward. Unlike the extension process, it is necessary to completely reproduce the parent type definition as part of the restriction definition. By omitting parts of the parent definition, the restriction element creates a new, constrained type. As an example, this <xs:complexType name="physicalAddressType"> <xs:sequence> <xs:element name="street" type="xs:string" maxOccurs="3"/> <xs:element name="city" type="xs:string"/> <xs:element name="state" type="xs:string"/> </xs:sequence> </xs:complexType> The restricted version looks like: <xs:complexType name="simplePhysicalAddressType"> <xs:complexContent> <xs:restriction base="addr:physicalAddressType"> <xs:sequence> <xs:element name="street" type="xs:string"/> <xs:element name="city" type="xs:string"/> <xs:element name="state" type="xs:string"/> </xs:sequence> </xs:restriction> </xs:complexContent> </xs:complexType> Notice that this type very closely resembles the Using derived typesOne of the chief benefits of creating derived types is that the derived type may appear in place of the parent type within an instance document. The Example 16-13. addressdoc.xml using a derived type<?xml version="1.0"?> <addr:address xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://namespaces.anonymous.com/xmlnut/address address-schema.xsd" xmlns:addr="http://namespaces.anonymous.com/xmlnut/address" addr:language="en" addr:ssn="123-45-6789"> . . . <physicalAddress addr:latitude="34.003855" addr:longitude="-81.034808" xsi:type="addr:simplePhysicalAddressType"> <street>1400 Main St.</street> <city>Columbia</city> <state>SC</state> </physicalAddress> . . . </addr:address> Notice that the Substitution GroupsA feature that is closely related to derived types is the substitution group. A substitution group is a collection of elements that are all interchangeable with a particular element, called the head element, within an instance document. To create a substitution group, all that is required is that an element declaration include a TIP: The primary restriction on substitution groups is that every element in the group must either be of the same type as or derived from the head element's type. Declaring a numeric element and trying to add it to a substitution group based on a string element would generate an error from the schema processor. The elements must also be declared globally and in the target namespace of the schema. |