• 沒有找到結果。

Basic Schema Reusability

在文檔中 Building Web Services with Java (頁 89-95)

The concept of reusability is important for XML Schema. Reusability deals with the question of how to best leverage existing assets in new projects. In schemas, the assets include element and attribute definitions, content model definitions, simple and complex datatypes, and whole schemas.We can roughly break down reusability mechanisms into two kinds: basic and advanced.The basic reusability mechanisms address the problems of using existing assets in multiple places. Advanced reusability mechanisms address the problems of modifying existing assets to serve needs that are different than those for which the assets were originally designed.

This section will address the following basic reusability mechanisms:

n Element references

n Content model groups

n Attribute groups

n Schema includes

n Schema imports

Element References

In XML Schema, you can define elements using a name and a type. Alternatively, ele-ment declarations can refer to preexisting eleele-ments using the refattribute of

65 XML Schemas

xsd:elementas follows, where a globally defined commentelement is reused for both person and task complex types:

<xsd:element name=”comment” type=”xsd:string”/>

<xsd:complexType name=”personType”>

<xsd:sequence>

<xsd:element name=”name” type=”xsd:string”/>

<xsd:element ref=”comment” minOccurs=”0”/>

</xsd:sequence>

</xsd:complexType>

<xsd:complexType name=”taskType”>

<xsd:sequence>

<xsd:element name=”toDo” type=”xsd:string”/>

<xsd:element ref=”comment” minOccurs=”0”/>

</xsd:sequence>

</xsd:complexType>

Content Model Groups

Element references are perfect for reusing the definition of a single element. However, if your goal is to reuse all or part of a content model, then element groups are the way to go. Element groups are defined using xsd:groupand are referred to using the same mechanism used for elements.The following schema fragment illustrates the concept. It extends the previous example so that instead of a single commentelement, public and private comment elements are reused as a group:

<xsd:group name=”comments”>

<xsd:sequence>

<xsd:element name=”publicComment” type=”xsd:string”

minOccurs=”0”/>

<xsd:element name=”privateComment” type=”xsd:string”

minOccurs=”0”/>

</xsd:sequence>

</xsd:group>

<xsd:complexType name=”personType”>

<xsd:sequence>

<xsd:element name=”name” type=”xsd:string”/>

<xsd:group ref=”comments”/>

</xsd:sequence>

</xsd:complexType>

<xsd:complexType name=”taskType”>

<xsd:sequence>

<xsd:element name=”toDo” type=”xsd:string”/>

<xsd:group ref=”comments”/>

</xsd:sequence>

</xsd:complexType>

Attribute Groups

The same reusability mechanism can be applied to commonly used attribute groups.The following example defines the ID/IDREFcombination of idandhrefattributes as a ref-erenceable attribute group. It’s then applied to both the person and the task type:

<xsd:attributeGroup name=”referenceable”>

<xsd:attribute name=”id” type=”xsd:ID”/>

<xsd:attribute name=”href” type=”xsd:IDREF”/>

</xsd:attributeGroup>

<xsd:complexType name=”personType”>

<xsd:sequence>

<xsd:element name=”name” type=”xsd:string”/>

</xsd:sequence>

<xsd:attributeGroup ref=”referenceable”/>

</xsd:complexType>

<xsd:complexType name=”taskType”>

<xsd:sequence>

<xsd:element name=”toDo” type=”xsd:string”/>

</xsd:sequence>

<xsd:attributeGroup ref=”referenceable”/>

</xsd:complexType>

Schema Includes and Imports

Element references and groups as well as attribute groups provide reusability within the same schema document. However, when you’re dealing with very complex schema or trying to achieve maximum reusability, you’ll often need to split a schema into several documents.The schema include and import mechanisms allow these documents to refer-ence one another.

Consider the scenario where SkatesTown is intent on reusing the schema definition for its address type for a mailing list schema. SkatesTown must solve three small prob-lems:

n Put the address type definition in its own schema document

n Reference this schema document from the purchase order schema document

n Reference this schema document from the mailing list schema document

67 XML Schemas

Pulling the address definition into its own schema is as easy as a cut-and-paste operation (see Listing 2.19). Even though this is a different document than the main purchase order schema, they both define portions of the SkatesTown PO namespace.The binding between schema documents and the namespaces they define isn’t one-to-one. It’s explic-itly identified by the targetNamespaceattribute of the xsd:schemaelement.

Listing 2.19 Standalone Address Type Schema

<?xml version=”1.0” encoding=”UTF-8”?>

<xsd:schema xmlns=”http://www.skatestown.com/ns/po”

xmlns:xsd=”http://www.w3.org/2001/XMLSchema”

targetNamespace=”http://www.skatestown.com/ns/po”>

<xsd:annotation>

<xsd:documentation xml:lang=”en”>

Address type schema for SkatesTown.

</xsd:documentation>

</xsd:annotation>

<xsd:complexType name=”addressType”>

<xsd:sequence>

<xsd:element name=”name” type=”xsd:string” minOccurs=”0”/>

<xsd:element name=”company” type=”xsd:string” minOccurs=”0”/>

<xsd:element name=”street” type=”xsd:string”

maxOccurs=”unbounded”/>

<xsd:element name=”city” type=”xsd:string”/>

<xsd:element name=”state” type=”xsd:string” minOccurs=”0”/>

<xsd:element name=”postalCode” type=”xsd:string”

minOccurs=”0”/>

<xsd:element name=”country” type=”xsd:string” minOccurs=”0”/>

</xsd:sequence>

<xsd:attribute name=”id” type=”xsd:ID”/>

<xsd:attribute name=”href” type=”xsd:IDREF”/>

</xsd:complexType>

</xsd:schema>

Referring to this schema is also easy. Instead of having the address type definition inline, the PO schema needs to include the address schema using the xsd:includeelement.

During the processing of the PO schema, the address schema will be retrieved and the address type definition will become available (see Listing 2.20).

Listing 2.20 Referring to the Address Type Schema

<?xml version=”1.0” encoding=”UTF-8”?>

<xsd:schema xmlns=”http://www.skatestown.com/ns/po”

xmlns:xsd=”http://www.w3.org/2001/XMLSchema”

targetNamespace=”http://www.skatestown.com/ns/po”>

<xsd:include

schemaLocation=”http://www.skatestown.com/schema/address.xsd”/>

...

</xsd:schema>

The mailing list schema is very simple. It defines a single mailingListelement that contains any number of contact elements whose type is address. Being an altogether different schema than that used for POs, the mailing list schema uses a new namespace:

http://www.skatestown.com/ns/mailingList. Listing 2.21 shows one possible way to define this schema.

Listing 2.21 Mailing List Schema

<?xml version=”1.0” encoding=”UTF-8”?>

<xsd:schema xmlns=”http://www.skatestown.com/ns/po”

xmlns:xsd=”http://www.w3.org/2001/XMLSchema”

targetNamespace=”http://www.skatestown.com/ns/mailingList”>

<xsd:include

schemaLocation=”http://www.skatestown.com/schema/address.xsd”/>

<xsd:annotation>

<xsd:documentation xml:lang=”en”>

Mailing list schema for SkatesTown.

</xsd:documentation>

</xsd:annotation>

<xsd:element name=”mailingList”>

<xsd:sequence>

<xsd:element name=”contact” type=”addressType”

minOccurs=”0” maxOccurs=”unbounded”/>

</xsd:sequence>

</xsd:element>

</xsd:schema>

This example uses xsd:includeto bring in the schema fragment defining the address type.There is no problem with that approach. However, there might be a problem with authoring mailing-list documents.The root of the problem is that the mailingListand

contactelements are defined in one namespace (http://www.skatestown.com/ns/

mailingList), whereas the elements belonging to the address type—name,company,

street,city,state,postalCode, andcountry—are defined in another

(http://www.skatestown.com/ns/po).Therefore, the mailing list document must refer-ence both namespaces (see Listing 2.22).

Listing 2.20 Continued

69 XML Schemas

Listing 2.22 Mailing List That References Two Namespaces

<?xml version=”1.0” encoding=”UTF-8”?>

<list:mailingList xmlns:list=”http://www.skatestown.com/ns/mailingList”

xmlns:addr=”http://www.skatestown.com/ns/po”

xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”

xsi:schemaLocation=”http://www.skatestown.com/ns/mailingList

http://www.skatestown.com/schema/mailingList.xsd http://www.skatestown.com/ns/po

http://www.skatestown.com/schema/address.xsd”>

<contact>

<addr:company>The Skateboard Warehouse</addr:company>

<addr:street>One Warehouse Park</addr:street>

<addr:street>Building 17</addr:street>

<addr:city>Boston</addr:city>

<addr:state>MA</addr:state>

<addr:postalCode>01775</addr:postalCode>

</contact>

</list:mailingList>

Ideally, when reusing the address type definition in the mailing list schema, we want to hide the fact that it originates from a different namespace and treat it as a true part of the mailing list schema.Therefore, the xsd:includemechanism isn’t the right one to use, because it makes no namespace changes.The reuse mechanism that will allow the merging of schema fragments from multiple namespaces into a single schema is the import mechanism. Listing 2.23 shows the new mailing list schema.

Listing 2.23 Importing Rather Than Including the Address Type Schema

<?xml version=”1.0” encoding=”UTF-8”?>

<xsd:schema xmlns=”http://www.skatestown.com/ns/po”

xmlns:xsd=”http://www.w3.org/2001/XMLSchema”

xmlns:addr=”http://www.skatestown.com/ns/po”

xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”

xsi:schemaLocation=”http://www.skatestown.com/ns/po http://www.skatestown.com/schema/address.xsd

targetNamespace=”http://www.skatestown.com/ns/mailingList”>

<xsd:import namespace=”http://www.skatestown.com/ns/po”/>

<xsd:annotation>

<xsd:documentation xml:lang=”en”>

Mailing list schema for SkatesTown.

</xsd:documentation>

</xsd:annotation>

<xsd:element name=”mailingList”>

<xsd:sequence>

<xsd:element name=”contact” type=”addr:addressType”

minOccurs=”0” maxOccurs=”unbounded”/>

</xsd:sequence>

</xsd:element>

</xsd:schema>

Although the mechanism is simple to describe, it takes several steps to execute:

1. Declare the namespace of the address type definition and assign it the prefix addr. 2. Use the standard xsi:schemaLocationmechanism to hint about the location of

the address schema.

3. Use xsd:importinstead of xsd:includeto merge the contents of the PO name-space into the mailing list namename-space.

4. When referring to the address type, use its fully qualified name:

addr:addressType.

The net result is that the mailing list instance document has been simplified (see Listing 2.24).

Listing 2.24 Simplified Instance Document That Requires a Single Namespace

<?xml version=”1.0” encoding=”UTF-8”?>

<list:mailingList xmlns:list=”http://www.skatestown.com/ns/mailingList”

xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”

xsi:schemaLocation=”http://www.skatestown.com/ns/mailingList

http://www.skatestown.com/schema/mailingList.xsd”>

<contact>

<company>The Skateboard Warehouse</company>

<street>One Warehouse Park</street>

<street>Building 17</street>

<city>Boston</city>

<state>MA</state>

<postalCode>01775</postalCode>

</contact>

</list:mailingList>

在文檔中 Building Web Services with Java (頁 89-95)