The W3C XML Schema Annotation Element

The recommended way to add comments and documentation in a W3C XML Schema is through the xs:annotation element. This element can be added within pretty much all the W3C XML Schema elements (in fact, it can be added within all the schema elements except xs:annotation and its child elements, xs:documentation and xs:appinfo ). It generally appears as the first child element (except for the xs:schema element in which xs:annotation can appear anywhere).

The xs:annotation element is a container for the xs:documentation and xs:appinfo elements that contain additional information. These two elements are dedicated to holding human readable documentation ( xs:documentation ) and machine-processable information ( xs:appinfo ). They accept any text and child elements. (These are the only W3C XML Schema elements that have a mixed content model.) Note, though, that the schema for schema specifies that the processing to apply to the content of these elements is lax. Concretely, this means that although W3C XML Schema elements can be included within these elements, they must be valid per the schema for schema. This mixed content model allows the inclusion of almost any content, such as text:

<xs:element name="author" type="author">
  <xs:annotation>
    <xs:documentation xml:lang="en">
      The author of a book.
    </xs:documentation>
    <xs:documentation xml:lang="fr">
      Designe l'auteur d'un livre.
    </xs:documentation>
  </xs:annotation>
</xs:element>

It also allows rich content, such as XHTML, which can be assembled to create more user friendly and readable documentation:

<xs:element name="author" type="author">
  <xs:annotation>
    <xs:documentation xml:lang="en">
      <p id="author" xmlns="http://www.w3.org/1999/xhtml">
        This element describes the
        <em>
          author
        </em>
        of a
        <a href="#book">
          book
        </a>
      </p>
      .
    </xs:documentation>
  </xs:annotation>
</xs:element>

It even allows SVG, such as the following, which provides a picture of what an author may look like:

<xs:element name="author" type="author">
  <xs:annotation>
    <xs:documentation>
      <svg xmlns="http://www.w3.org/2000/svg">
        <title>
          An author
        </title> 
        <ellipse style="stroke:#000000; fill:#e3e000;
          stroke-width:2pt;" id="head" cx="280" cy="250" rx="110"
          ry="130"/> 
        <ellipse style="stroke:none; fill:#7f7f7f; " id="leftEye"
          cx="240"cy="225" rx="18" ry="18"/> 
        <ellipse style="stroke:none; fill:#7f7f7f; " id="rightEye"
          cx="320"cy="225" rx="18" ry="18"/> 
        <path style="fill:none;stroke:#7F7F7F; stroke-width:5pt;"
          id="mouth"d="M 222 280 A 58 48 0 0 0 338 280"/>
      </svg>
    </xs:documentation>
  </xs:annotation>
</xs:element>

Dublin Core elements are a set of elements widely used on the Web to qualify web pages and supported by a large range of applications. They may be used as general purpose metadata embedded within annotations:

<xs:element name="author" type="author">
  <xs:annotation>
    <xs:appinfo xmlns:dc="http://purl.org/dc/elements/1.1/">
      <dc:creator>
        Eric van der Vlist (mailto:vdv@dyomedea.com)
      </dc:creator>
      <dc:date>
        2002-02-01
      </dc:date>
      <dc:subject>
        author,person,book
      </dc:subject>
      <dc:description>
        This element describes the author of a book.
      </dc:description>
    </xs:appinfo>
  </xs:annotation>
</xs:element>

Annotations are also a good container for application-specific metadata, such as those used by the schema for schema to describe the list of facets and properties of its primitive datatypes:

<xs:simpleType name="string" id="string">
  <xs:annotation>
    <xs:appinfo>
      <hfp:hasFacet name="length"/>
      <hfp:hasFacet name="minLength"/>
      <hfp:hasFacet name="maxLength"/>
      <hfp:hasFacet name="pattern"/>
      <hfp:hasFacet name="enumeration"/>
      <hfp:hasFacet name="whiteSpace"/>
      <hfp:hasProperty name="ordered" value="false"/>
      <hfp:hasProperty name="bounded" value="false"/> 
      <hfp:hasProperty name="cardinality" value="countably
        infinite"/>
      <hfp:hasProperty name="numeric" value="false"/>
    </xs:appinfo> 
    <xs:documentation
      source="http://www.w3.org/TR/xmlschema-2/#string"/>
  </xs:annotation>
  <xs:restriction base="xs:anySimpleType">
    <xs:whiteSpace value="preserve" id="string.preserve"/>
  </xs:restriction>
</xs:simpleType>

The Schema Adjunct Framework (SAF) is a proposal to complement schemas with the information needed to generate applications. It is found at http://www.extensibility.com/saf/. One of its syntaxes, " schema adornments,” also uses xs:appinfo ; although this syntax hasn’t been adapted to the W3C XML Schema Recommendation yet, it could be something like this (note that this is my own unofficial adaptation given here just as an example):

<xs:element name="author" type="author">
  <xs:annotation> 
    <xs:appinfo source="saf:meta-data-item"
      xmlns:sql="http://www.extensibility.com/saf/spec/safsample/sql-map.saf"
      >
      <sql:select>
        select
        <sql:elem>
          name
        </sql:elem>
        ,
        <sql:elem>
          birthdate
        </sql:elem>
        ,
        <sql:attr>
          deathdate
        </sql:attr>
        from tbl_author
      </sql:select>
    </xs:appinfo>
  </xs:annotation>
</xs:element>

SAF also defines a syntax to embed rules written as XPath expressions, which is also the domain of Schematron (which is discussed in Appendix A). Schematron rules can be embedded in xs:appinfo elements and used to test things that W3C XML Schema cannot—like ensuring that the birth of a person took place before their death.

How can this work, given that the XPath 1.0 on which Schematron is built can’t interpret dates? This is a fairly dangerous practice, but assuming that the dates use four digits for the years, as well as the same time zone (which we saw how to impose through patterns in Chapter 6), this works because ISO 8601 dates are then following the alphabetical sort order!

<xs:element name="author" type="author">
  <xs:annotation>
    <xs:appinfo xmlns:sch="http://www.ascc.net/xml/schematron">
      <sch:pattern name="Born before dead">
        <sch:rule context="author"> 
          <sch:assert test="not(dead) or (dead > born)"
            diagnostics="bornAfterDead">
            An author should die after her or his death.
          </sch:assert>
          <sch:diagnostics>
            <sch:diagnostic id="bornAfterDead"> 
              Error, this author is born after her or his birth!
              Author=
              <sch:value-of select="name"/>
              Birth =
              <sch:value-of select="born"/>
              Death =
              <sch:value-of select="dead"/>
            </sch:diagnostic>
          </sch:diagnostics>
        </sch:rule>
      </sch:pattern>
    </xs:appinfo>
  </xs:annotation>
</xs:element>

Although not a common practice, it is also possible to embed code snippets, such as this XSLT template:

<xs:element name="book" type="book">
  <xs:annotation>
    <xs:appinfo xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:template match="book">
        <xsl:apply-templates select="title"/>
        <xsl:apply-templates select="isbn"/>
        <p>
          Authors:
        </p>
        <ul>
          <xsl:apply-templates select="author"/>
        </ul>
        <p>
          Characters:
        </p>
        <ul>
          <xsl:apply-templates select="character"/>
        </ul>
      </xsl:template>
    </xs:appinfo>
  </xs:annotation>
</xs:element>

Instead of embedding resources, you can also link them using XLink. RDDL, a vocabulary aimed at describing namespaces may be diverted from its original goal to provide the glue for expressing these links:

<xs:element name="author" type="author">
  <xs:annotation> 
    <xs:appinfo xmlns:xlink="http://www.w3.org/1999/xlink"
      xmlns:rddl="http://www.rddl.org/"> 
      <rddl:resource id="author-transform"
        xlink:arcrole="http://www.w3.org/1999/xhtml"
        xlink:role="http://www.w3.org/1999/XSL/Transform"
        xlink:title="Author template"
        xlink:href="library.xslt#author">
        <div class="resource">
          <h4>
            XSLT Transformation
          </h4>
          <p>
            This
            <a href="library.xslt#author">
              template
            </a>
            displays the description of an author.
          </p>
        </div>
      </rddl:resource> 
      <rddl:resource id="CSS" xlink:title="CSS Stylesheet"
        xlink:role="http://www.isi.edu/in-notes/iana/assignments/media-types/text/css"
        xlink:href="author.css">
        <div class="resource">
          <h4>
            CSS Stylesheet
          </h4>
          <p>
            A
            <a href="author.css">
              CSS stylesheet
            </a> 
            defining the styles which may be used to display an author.
          </p>
        </div>
      </rddl:resource>
    </xs:appinfo>
  </xs:annotation>
</xs:element>

RDDL should be pronounced “riddle,” and its specification is available at http://rddl.org.

Tip

xs:documentation and xs:appinfo both accept an optional source attribute, which is a URI, and can identify the source or the nature of the included information. Since it’s designed for human consumption, xs:documentation also accepts an optional xml:lang attribute.