Extensibility

MSXML 5.0 SDK

Microsoft XML Core Services (MSXML) 5.0 for Microsoft Office - XML Schemas

Extensibility

Unlike a document type definition (DTD), XML-Data Reduced (XDR) schemas are extensible. That is, they are built on an open content model. Schema authors are free to add their own elements and attributes to XDR schema documents. For example, you can add additional constraints to a declaration for a pages element. The following sample code declares the pages element and assigns it an int data type. Extended tags from the myExt namespace are used to augment this information with an added limitation that books must have a minimum of 50 pages and a maximum of 100 pages.

<ElementType name="pages" xmlns:myExt="urn:myschema-extensions">
  <datatype dt:type="int" />
  <myExt:min>50</myExt:min>
  <myExt:max>100</myExt:max>
</ElementType>

Although validation will only check that the value of a particular pages element is an integer, your application can use the information provided by the added elements in the myExt namespace to perform additional validation.

Use of a namespace is a requirement for adding elements and attributes to a schema. For more information about namespaces, see Using Namespaces in Documents.

Referencing Other Schemas

Custom schemas can be built out of standard parts. For example, suppose that a definition for an Address element from another schema has met your needs. With namespaces, this schema can be used directly with a reference to the original schema rather than copying the definition.

To reference an element defined in another schema, you must first use a namespace declaration to introduce the other schema. This declaration consists of an attribute beginning with "xmlns:", followed by a name of your choice, called the prefix, and a value that is the Uniform Resource Identifier (URI) of the other schema.

<ElementType name="PurchaseOrder"
             xmlns:abcde="http://contoso.com/stuff.xml">

The schema has a namespace URI of "http://contoso.com/stuff.xml" and a prefix of "abcde". The namespace URI identifies the other schema precisely; the prefix is a local name that you now use to refer to that schema and to the elements it defines as though they were defined in your schema. If the other schema has a suitable shipTo element defined, you can use it by writing the following.

<ElementType name="shipTo"
             xmlns:abcde="http://contoso.com/stuff.xml">
   <element type="abcde:Address"/>
</ElementType>

In the type attribute of the first child element declaration for the value "abcde:Address", the prefix "abcde" is matched to the enclosing namespace declaration; thus, "abcde:Address" has the effect of meaning "the Address element" as defined in the schema "http://contoso.com/stuff.xml".

However, this has an effect on the XML document as well. For example, in the following purchase order document you must also reference the other schema namespace.

<PurchaseOrder xmlns:abcde="http://contoso.com/stuff.xml">
  <shipTo>
    <abcde:Address>
      <abcde:name>Alice Smith</abcde:name>
      <abcde:street>123 Maple Street</abcde:street>
      <abcde:city>Mill Valley</abcde:city>
      <abcde:state>CA</abcde:state>
      <abcde:zip>90952</abcde:zip>
    </abcde:Address>
  </shipTo>
  <orderDate>1999-05-20</orderDate>
  <shipDate>1999-05-25</shipDate>
  <comments>
    Get these things to me in a hurry, my lawn is going wild!
  </comments>
  <Items>
    <Item>
      <productName>Lawnmower, model BUZZ-1</productName>
      <quantity>1</quantity>
      <price>148.95</price>
    </Item>
    <Item>
      <productName>Weed Wacker, model SNOOZE-2</productName>
      <quantity>1</quantity>
      <price>39.98</price>
    </Item>
  </Items>
</PurchaseOrder>

You can determine that the Address element is defined by the schema at http://contoso.com/stuff.xml. When you build specialized schemas from more widely understood standard parts, like the preceding Address element, those portions can often be processed by standard software components. For example, if you have an Extensible Stylesheet Language (XSL) template available for the Address element, as defined in the schema http://contoso.com/stuff.xml, you can reuse this general purpose address styling code anywhere that Address appears.

The same prefix is used in both the schema and in the document instance: in the schema for all purchase orders, and in a specific purchase order. However this is not necessary, because the prefix is only a local alias for the namespace URI, and you can use any prefix in the document instance. You are only required to use the same prefix in a document when you declare the namespace and when you use elements from that namespace, as in the following example.

<PurchaseOrder xmlns:z="http://contoso.com/stuff.xml">
  <shipTo>
    <z:Address>
      <z:name>Alice Smith</z:name>
      <z:street>123 Maple Street</z:street>
      <z:city>Mill Valley</z:city>
      <z:state>CA</z:state>
      <z:zip>90952</z:zip>
    </z:Address>
  </shipTo>
</PurchaseOrder>

The declaration of a namespace is scoped to the element on which it appears. It makes the namespace prefix available, and associates it with the namespace URI for that element and anything it contains, unless overridden by another, enclosed namespace declaration. Therefore, because the namespace is only used on the Address element, the namespace declaration can appear on the Address element instead, as follows.

<PurchaseOrder>
  <shipTo>
    <z:Address xmlns:z="http://contoso.com/stuff.xml">
      <z:name>Alice Smith</z:name>
      <z:street>123 Maple Street</z:street>
      <z:city>Mill Valley</z:city>
      <z:state>CA</z:state>
      <z:zip>90952</z:zip>
    </z:Address>
  </shipTo>
</PurchaseOrder>

Omitting Prefixes

You can also omit a prefix to a namespace, which can make for more legible documents. In the following example, by omitting the prefix from the namespace declaration, you indicate that any child element without a prefix is defined by the specified namespace.

<PurchaseOrder>
  <shipTo>
    <Address xmlns="http://contoso.com/stuff.xml">
      <name>Alice Smith</name>
      <street>123 Maple Street</street>
      <city>Mill Valley</city>
      <state>CA</state>
      <zip>90952</zip>
    </Address>
  </shipTo>
</PurchaseOrder>

Namespace prefixes are only for intra-document bookkeeping. The corresponding namespace URI is what is important, so all four of the Address elements in the preceding examples mean exactly the same thing.

Although the Address element has been identified as being defined by the schema http://contoso.com/stuff.xml, PurchaseOrder has not been similarly tied to a schema. To do this, assuming a schema named http://fabrikam.com/PO.xml defines a PurchaseOrder, you can write the following.

<PurchaseOrder xmlns="http://fabrikam.com/PO.xml">
  <shipTo>
    <Address xmlns="http://contoso.com/stuff.xml"  >
      <name>Alice Smith</name>
      <street>123 Maple Street</street>
      <city>Mill Valley</city>
      <state>CA</state>
      <zip>90952</zip>
    </Address>
  </shipTo>
  <orderDate>1999-05-20</orderDate>
  <shipDate>1999-05-25</shipDate>
  <comments>
     Get these things to me in a hurry, my lawn is going wild!
  </comments>
  <Items>
    <Item>
      <productName>Lawnmower, model BUZZ-1</productName>
      <quantity>1</quantity>
      <price>148.95</price>
    </Item>
    <Item>
      <productName>Baby Monitor, model SNOOZE-2</productName>
      <quantity>1</quantity>
      <price>39.98</price>
    </Item>
  </Items>
</PurchaseOrder>

This declares that the PurchaseOrder element and all elements it contains are defined within the schema http://fabrikam.com/PO.xml, except for Address and the elements it contains, which are defined within xmlns="http://contoso.com/stuff.xml. In both cases, explicit prefixes are omitted.

Multiple Namespaces

You can declare multiple namespaces on a single element. You can also use several prefixes to refer to the same namespace. The following example demonstrates this can be done and shows that this document is functionally equivalent to the previous one.

<PurchaseOrder xmlns:a="http://fabrikam.com/PO.xml"
xmlns:b="http://contoso.com/stuff.xml"
xmlns:c="http://contoso.com/stuff.xml">
  <a:shipTo>
    <b:Address >
      <c:name>Alice Smith</c:name>
      <b:street>123 Maple Street</b:street>
      <c:city>Mill Valley</c:city>
      <b:state>CA</b:state>
      <c:zip>90952</c:zip>
    </b:Address>
  </a:shipTo>
  <a:orderDate>1999-05-20</a:orderDate>
  <a:shipDate>1999-05-25</a:shipDate>
  <a:comments>
      Get these things to me in a hurry, my lawn is going wild!
  </a:comments>
  <a:Items>
    <a:Item>
      <a:productName>Lawnmower, model BUZZ-1</a:productName>
      <a:quantity>1</a:quantity>
      <a:price>148.95</a:price>
    </a:Item>
    <a:Item>
      <a:productName>Baby Monitor</a:productName>
      <a:quantity>1</a:quantity>
      <a:price>39.98</a:price>
    </a:Item>
  </a:Items>
</a:PurchaseOrder>

Open Content Model

If a document schema has elements with an open content model, you can include elements not mentioned in the original schema, provided they are assigned to a specific namespace, either with a default namespace in scope or with a prefix. You can also include undefined attributes in an element, provided the attribute is qualified by a prefix and the prefix is in scope. For example, suppose that a third schema defines an element called trackingInformation. Because PurchaseOrder is defined as having an open content model, you can simply add this element directly to the instance.

<PurchaseOrder xmlns="http://fabrikam.com/PO.xml">
  <shipTo>
    <Address xmlns="http://contoso.com/stuff.xml">
      <name>Denise Smith</name>
      <street>123 Maple Street</street>
      <city>Mill Valley</city>
      <state>CA</state>
      <zip>90952</zip>
    </Address>
  </shipTo>
  <orderDate>1999-05-20</orderDate>
  <shipDate>1999-05-25</shipDate>
  <comments>
      Get these things to me in a hurry. My lawn is going wild!
  </comments>
  <Items>
    <Item>
      <productName>Lawnmower, model BUZZ-1</productName>
      <quantity>1</quantity>
      <price>148.95</price>
    </Item>
    <Item>
      <productName>Baby Monitor, model SNOOZE-2</productName>
      <quantity>1</quantity>
      <price>39.98</price>
    </Item>
  </Items>
  <trackingInformation xmlns="http://example.microsoft.com/tracking.xml">
    <route>1234-5678</route>
    <signature>32143912850-3959159=1395</signature>
  </trackingInformation>
</PurchaseOrder>

Because namespace qualification is required for any undefined attribute or element, the trackingInformation element would not have been valid if its xmlns attribute had been omitted.