Built-In Datatypes

Namespaces

Namespaces are leveraged heavily in XML schemas, so I can't go much further without first discussing what namespaces are and how they are defined.

Namespaces provide logical boundaries for entities defined within a schema. For example, in the previous section I created a schema that defines the Amount element. What if someone else defines an Amount element? If an Amount element appears in an instance document, how do I know whether it is an instance of the one defined by my schema or theirs? If each Amount element were defined within a separate namespace, the Amount element would be fully qualified to a particular namespace and therefore would be unambiguous.

targetNamespace Attribute

The targetNamespace attribute is used to set the identifier of the namespace. The value of this attribute is a URI that serves as an opaque pointer to reference the namespace. The following are examples of valid identifiers for namespaces:

http://somedomain.com/ http://somedomain.com/Commerce urn:Commerce-SomeDomain-Com urn:Com:SomeDomain:Commerce urn:WebService:SoapBased:Commerce

The first two URIs are URLs that specify a registered domain name. The last three URIs are location-independent Uniform Resource Names (URNs). One of the benefits of defining a namespace within the context of a registered domain name is that you avoid potential naming collisions with namespaces defined by others.

A namespace identified by a URI is defined within a schema document. Entities that can be scoped to namespaces include datatypes, elements, and attributes. Within an XML Schema document, the schema element can contain a targetNamespace parameter that contains a URI for the schema.

The following code defines a namespace of the schema for the Commerce Web service. For now, it contains the definition for the Amount element. I will enhance it later.

<?xml version='1.0'?> <schema xmlns='http://www.w3.org/2001/XMLSchema' targetNamespace='urn:Commerce'>   <!-- Response Message (work-in-progress) -->   <element name='Amount'/> </schema>

I added the targetNamespace attribute to the schema element and then set its value to the Commerce URN. All entities defined by the schema are scoped within the Commerce namespace. In this case, the only entity defined is the Amount element.

xmlns Attribute

To fully qualify the entities referenced within an XML document, you need to reference one or more schemas. XML documents that reference schemas are instance documents and schemas themselves. Instance documents must refer to the namespace URI in order to fully qualify the entities referenced. You can accomplish this by adding an xmlns attribute to any element within the document. Here is an example:

<?xml version='1.0'?> <Amount xmlns='urn:Commerce'>123.45<Amount/>

In the instance document, I set the default namespace to Commerce. As a result, Amount and its subelements, if it had any, are fully qualified within the Commerce namespace.

When you reference a namespace, you can assign the reference a moniker. The assignment of a moniker to a referenced namespace takes the form of xmlns:moniker='SomeURI'. You can then use the moniker to fully qualify entities appearing within the XML document that are defined within the referenced namespace.

To fully qualify an entity such as a type definition or an element declaration, you prefix the entity with the moniker followed by a colon. You saw this type of use of namespace monikers in the previous chapter. All of the example SOAP messages defined the soap: namespace moniker within the reference to the SOAP schema, as shown here:

<?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">   <soap:Body>     <!-- SOAP message -->   </soap:Body> </soap:Envelope>

It is often necessary to reference multiple schemas. You can do this by adding multiple xmlns attributes. These are often added to the root element of the document for better readability and developer convenience. However, schema references can be made in any element within the instance document. Here is a SOAP message that contains two Amount elements in the message body:

<?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">   <soap:Body>     <Amount xmlns='urn:Commerce'>123.45</Amount>     <soap:Amount xmlns:soap='urn:Commerce'>123.45</soap:Amount>   </soap:Body> </soap:Envelope>

Even though I used different syntax, both Amount elements in the preceding document are equivalent. Let's look at how I used the individual namespace references.

Three namespace references were made. The first reference was made in the root element and defines the soap: moniker that is used to fully qualify entities referenced in the SOAP Envelope schema. The second reference sets Commerce as the default namespace for the first Amount element and its child elements (if any existed). The final reference overrides the soap: moniker defined earlier to instead reference the Commerce schema for the second Amount element and its children (if any existed).

Namespace references apply to the element that contains the xmlns attribute and all of its child elements. Therefore, if a namespace declaration is made within the SOAP Header element, the declaration applies to all elements within the header. Because references are scoped to the element in which they are declared, the reference made in the SOAP Header element does not apply to the SOAP Body element or any of its child elements.

Namespace references are also used heavily in schema documents. Within schema documents, it is often necessary to reference entities defined within the document. You can do this by creating a reference within the schema document to itself. By convention, this reference is usually associated with the tns: moniker, which is short for “this namespace.” Here is a portion of the SOAP Envelope schema that shows the use of the tns: moniker:

<?xml version='1.0'?> <!-- XML Schema for SOAP v 1.1 Envelope --> <!-- Copyright 2000 DevelopMentor, International Business Machines Corporation,      Lotus Development Corporation, Microsoft, UserLand Software --> <schema xmlns='http://www.w3.org/1999/XMLSchema'         xmlns:tns='http://schemas.xmlsoap.org/soap/envelope/'         targetNamespace='http://schemas.xmlsoap.org/soap/envelope/'>         <!-- Definition for the Envelope element -->   <element name="Envelope" type="tns:Envelope"/>   <!-- Definition for the Envelope type -->   <complexType name='Envelope'>     <element ref='tns:Header' minOccurs='0'/>     <element ref='tns:Body' minOccurs='1'/>     <any minOccurs='0' maxOccurs='*'/>     <anyAttribute/>   </complexType>   <!-- The rest of the SOAP Envelope schema... --> </schema>

The schema element sets the target namespace to http://schemas.xmlsoap.org/soap/envelope/. It also contains a reference to itself that is given the moniker tns:. The schema defines the Envelope element. The Envelope element is declared as type Envelope. Because the type definition is contained within the schema, it is prefixed by tns:.

schemaLocation Attribute

The URI of a namespace reference is an opaque pointer. So even if the URI is specified in the form of a URL, you cannot count on it to resolve to the actual schema document. However, you can use the schemaLocation attribute to give the parser hints on where the schema documents that define the referenced namespaces are located.

The value of the schemaLocation attribute is a whitespace-delimited string. It contains the URI of the schema followed by the URL that resolves to the schema document that is used to define the namespace. Multiple hints can be given within a single schemaLocation attribute. Here is an example:

<?xml version='1.0'?> <Amount xmlns='urn:Commerce'  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'  xsi:schemaLocation='urn:Commerce http://somedomain/Commerce.xsd  http://www.w3.org/2001/XMLSchema-instance  http://www.w3.org/2001/XMLSchema.xsd'>   123.45 </Amount>

For illustrative purposes, the instance document references two namespaces, the Commerce namespace and the XML Schema Instance namespace. Because the URI for the Commerce schema is in the form of a URN, it is not resolvable. However, even though the URI for the XML Schema Instance schema is in the form of a URL, it is not directly resolvable either. Therefore, I use the schemaLocation attribute to provide a hint about where the schema documents for the associated namespace URIs can be located.

I will cover a couple more points regarding the schemaLocation attribute before moving on to the next topic. The schemaLocation attribute can be applied to any element within the instance document. However, unlike most other XML Schema attributes, the schemaLocation attribute stays in effect for the remainder of the document, not just for its child elements. Finally, because the schemaLocation attribute serves as a hint, the parser might choose to locate the schema document for a particular namespace using some other method.

noNamespaceSchemaLocation Attribute

Schemas are not required to define namespaces. You can use the noNamespace-SchemaLocation attribute to reference schemas with no namespace. Here is an example:

<?xml version='1.0'?> <!-- File named Commerce.xsd --> <schema>   <!-- Response Message (work-in-progress) -->   <element name='Amount' type=/> </schema>

I defined a schema without a namespace definition that is contained within the file Commerce.xsd. Next I will create an instance document that references the schema:

<?xml version='1.0'?> <Amount xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'  xsi:noNamespaceSchemaLocation='file:Commerce.xsd'>   123.45 </Amount>

Because the Amount element is not defined within a namespace, I used the noNamespaceSchemaLocation attribute to reference the schema. The Amount element is then fully qualified with respect to the Commerce.xsd schema.

Even though entities not defined within a namespace can be referenced, this syntax is awkward and fragile. Therefore, you should avoid defining schemas without namespaces. If you do have to reference a schema that does not contain a namespace definition, consider importing the schema into a namespace definition. I discuss importing schemas later in this chapter.

XML Schema and XML Schema Instance Namespaces

The XML specification defines two fundamental namespaces, the XML Schema namespace and the XML Schema Instance namespace. Even though they share a common subset of entities such as type, element, and attribute definitions, each namespace serves a specific purpose. The XML Schema namespace should be referenced within schema documents, and the XML Schema Instance namespace should be referenced within instance documents.

The XML Schema namespace contains the entities used to define schemas. For example, the element and schema elements used in the Commerce schema are defined in the XML Schema namespace. The URI for the XML Schema namespace is http://www.w3.org/2001/XMLSchema, and by convention the namespace is often referenced by the xsd: moniker.

The XML Schema Instance namespace should be referenced by instance documents that use entities defined within the namespace. For example, the schemaLocation attribute used in instance documents is defined within the XML Schema Instance namespace. The URI for the XML Schema Instance namespace is http://www.w3.org/2001/XMLSchema-instance, and by convention the namespace is often referenced by the xsi: moniker.



Building XML Web Services for the Microsoft  .NET Platform
Building XML Web Services for the Microsoft .NET Platform
ISBN: 0735614067
EAN: 2147483647
Year: 2002
Pages: 94
Authors: Scott Short

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net