Schema Extensibility

This topic will explain how you can change the MAML schema so that you can use elements from other namespaces as well. This is useful when extending Sandcastle with build components that provide new elements because it still allows you to validate your topic files.

  Tip

The Sandcastle version of the MAML schema files already contain the necessary changes.

XML Schema Extensibility

In general, XML schema provides the any element for declaring extensibility points in your schema. The any element has two attributes that control the extensibility contract.

The namespace attribute allows you to either explicitly specify a closed set of namespaces that are allowed or to specify one of these pseudo-URIs:

##local

This allows only to use elements that do not reside in any namespace. This is not what we want to use because it forces build component authors to declare all elements in the empty namespace. This could easily lead to name clashes between different build components.

##targetNamespace

This only allows elements from the target namespace of the declaring schema. For our purposes this is useless because it would only allow elements from the MAML namespace (http://ddue.schemas.microsoft.com/authoring/2003/5).

##any

This allows any namespace, including the target namespace of the declaring schema. We do not want to use this because it would also allow to use any element from the MAML namespace (http://ddue.schemas.microsoft.com/authoring/2003/5) itself and hence undermine the schema validation for MAML.

##other

This allows any namespaces except the target namespace of the declaring schema. For our purposes this is ideal because it allows only to use elements from any namespace except the MAML namespace (http://ddue.schemas.microsoft.com/authoring/2003/5).

The processContents attribute allows you to control the validation requirements. It can have one of following values:

skip

This is the least restrictive value. It specifies that the schema processor should not try to validate the contents of the new element, even if it is able to find a schema for it.

strict

This is the most restrictive setting. It requires the schema processor to always validate the contents of the new element. If it is not able to find such a schema an error is reported during validation.

lax

This is a compromise between the settings skip and strict. The schema processor will validate the schema if it is able to find a schema for the new element and will skip it if cannot find such a schema. For our purposes this is ideal because it allows build component authors to provide a schema for validation but does not force them to do so.

Therefore, our extensibility points will all look like this:

XML
<any namespace="##other" processContents="lax" />

Extending Inline Text

Build components might add elements that you can use inside a para element. Examples for such elements are:

Linking

These are elements that allow you to link to other topics. MAML itself already provides several elements for this purpose, such as the link element to link to conceptual topics, the codeEntityReference element to link to managed code APIs, and the externalLink element to link to some location in the internet.

Semantics

This category includes elements that are used to associate pieces of text with semantics. In many cases these semantics are made visible through a consistent formatting, such as italics or bold text. Amongst others MAML itself provides the localUri element for marking text as representing local paths and the ui element for marking text as representing elements in your user interface.

To extend the para element we will extend the underlying type inlineType.

Open the file inline.xsd, goto line 62, and add the any element to the type:

XML
<complexType name="inlineType" mixed="true">
  <annotation>
    <documentation>
      The inlineType complexType describes a simple inline-only
      content model. It provides both text and elements with
      similarly simple content models.
    </documentation>
  </annotation>
  <choice minOccurs="0" maxOccurs="unbounded">
    <group ref="maml:inlineGroup"/>
    <element ref="maml:sharedContent"/>
    <element name="conditionalSection">
      <complexType>
        <sequence>
          <element ref="maml:conditions"/>
          <element name="conditionalContent" type="maml:inlineType"/>
        </sequence>
      </complexType>
    </element>
    <!-- PATCH HERE -->
    <any namespace="##other" processContents="lax" />
  </choice>
  <attributeGroup ref="maml:contentIdentificationSharingAndConditionGroup"/>
</complexType>

Extending Related Topics

For build components that provide elements for linking we also want to be able to use them inside the relatedTopics element. To do this, we will extend the type relatedTopicsType.

Open the file hierarchy.xsd, goto line 123 and add the any element to the type:

XML
<complexType name="relatedTopicsType" mixed="false">
  <choice minOccurs="0" maxOccurs="unbounded">
    <group   ref="maml:relatedTopicLinkGroup"/>
    <!-- PATCH HERE -->
    <any namespace="##other" processContents="lax" />
  </choice>
  <attributeGroup ref="maml:contentIdentificationSharingAndConditionGroup"/>
</complexType>

Extending Section Structure

Last but not least build components might also provide elements that allow you to build a structure. For this purpose MAML itself already provides the table, code, and para elements. To allow new structural elements we have to extend the type sectionContentType.

Open the file structure.xsd, goto line 66 and add the any element to the type:

XML
<complexType name="sectionContentType" mixed="false">
  <choice minOccurs="0" maxOccurs="unbounded">
    <group ref="maml:structureGroup"/>
    <element name="conditionalSection" type="maml:conditionalSectionType"/>
    <!-- PATCH HERE -->
    <any namespace="##other" processContents="lax" />
  </choice>
  <attributeGroup ref="maml:contentIdentificationSharingAndConditionGroup"/>
</complexType>

See Also