Examplotron

2. Table of contents

  1. Header
  2. Table of contents
  3. Purposes
  4. Limitations
  5. Tutorial
    1. Getting started.
    2. What about the attributes?
    3. Occurrences
    4. More control over occurrences
    5. Namespaces
    6. Mixed Content
    7. Iconic Datatypes
    8. More control over content models
    9. More control over simple types
    10. More on attributes
    11. Flat schemas
    12. Assertions
    13. Default values
  6. Resources
  7. To do
  8. Acknowledgements
  9. History
  10. Legal Statement

3. Purposes

The purpose of examplotron is to use instance documents as a lightweight schema language-- eventually adding the information needed to guide a validator in the sample documents.

"Classical" XML validation languages such as DTDs, W3C XML Schema, Relax, Trex or Schematron rely on a modeling of either the structure (and eventually the datatypes) that a document must follow to be considered as valid or on the rules that needs to be checked.

This modeling relies on specific XML serialization syntaxes that need to be understood before one can validate a document and is very different from the instance documents and the creation of a new XML vocabulary involves both creating a new syntax and mastering a syntax for the schema.

Many tools (including popular XML editors) are able to generate various flavors of XML schemas from instance documents, but these schemas do not find enough information in the documents to be directly useable leaving the need for human tweaking and the need to fully understand the schema language.

Examplotron may then be used either as a validation language by itself, or to improve the generation of schemas expressed using other XML schema languages by providing more information to the schema translators.

Examplotron aims to be both very visual (John Cowan said that "its virtue is iconicity") and complete. Both aspects are contradictory and the principle of Examplotron is to follow the 80/20 rule and make no compromize for its iconicity for the 80% of the features which are most common and borrow the Relax NG elements in its own namespace to insure that it is complete.

The "iconic" 80% include:

This release in an intermediate release where most of the "iconic 80%" has been implemented and the "complemental 20%" left for a next release.

4. Limitations

The obvious limitation of working with sample documents is that while this is very efficient to describe patterns that can be "shown" in a document, this cannot by itself be used to describe abstract "constructed" patterns.

To workaround this limitation, Examplotron relies on annotations, moving to an hybrid schema language involving both pure "schema by example" and modeling or rules construction.

Annotations through attributes are non intrusive and considered as part of the inconic 80% (the definition of mandatory attributes being the only exception which is done through an element).

Annotations through elements is done using elements imported from Relax NG and constitute the "complemental 20%". They include:

5. Tutorial

5.1. Getting started.

This first instance document (examplotron1.xml) is also a examplotron schema:

<?xml version="1.0" encoding="UTF-8"?>
<foo>
	<bar>My first examplotron.</bar>
	<baz>Hello world!</baz>
</foo>

This schema will validate all the documents without any namespace and the "same" structure, i.e. three element nodes (a document element of type "foo" with exactly two children elements "bar" and "baz") and no attributes.

The examplotron compiler (i.e. the compile.xsl XSLT sheet) transforms the examplotron schema into a Relax NG schema (examplotron1.rng) that can be applied to any document to check if it has the same structure.

The structure of examplotron1.rng (and therefore the transformation defined in compile.xsl) is very straightforward:

<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:ega="http://examplotron.org/annotations/"
         xmlns:sch="http://www.ascc.net/xml/schematron"
         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
   <start>
      <element name="foo">
         <element name="bar">
            <text>
               <ega:example>My first examplotron.</ega:example>
            </text>
         </element>
         <element name="baz">
            <text>
               <ega:example>Hello world!</ega:example>
            </text>
         </element>
      </element>
   </start>
</grammar>

Don't let the declarations and annotations confuse you. We will see in the next sections the use of these declarations and the annotations (such as "<ega:example>Hello world!</ega:example>") are there to carry the samples from Examplotron to Relax NG and insure that the Relax NG schema could be converted back into Examplotron if needed.

5.2. What about the attributes?

Attributes are also supported as shown by examplotron2.xml:

<?xml version="1.0" encoding="UTF-8"?>
<foo>
	<bar true="no longer">My first examplotron.</bar>
	<baz>Hello world</baz>
</foo>

Which will include the definition of the "true" attribute as optional (examplotron2.rng):

<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:ega="http://examplotron.org/annotations/"
         xmlns:sch="http://www.ascc.net/xml/schematron"
         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
   <start>
      <element name="foo">
         <element name="bar">
            <optional>
               <attribute name="true">
                  <ega:example true="no longer"/>
               </attribute>
            </optional>
            <text>
               <ega:example>My first examplotron.</ega:example>
            </text>
         </element>
         <element name="baz">
            <text>
               <ega:example>Hello world</ega:example>
            </text>
         </element>
      </element>
   </start>
</grammar>

Note that to declare mandatory attributes you would need to use the "complemental 20%".

5.3. Occurrences

What if we needed several elements "bar"? Just tell it (occurrences.eg):

<?xml version="1.0" encoding="UTF-8"?>
<foo>
	<bar>My first examplotron.</bar>
	<bar>Hello world!</bar>
</foo>

And this will give (occurrences.rng):

<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:ega="http://examplotron.org/annotations/"
         xmlns:sch="http://www.ascc.net/xml/schematron"
         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
   <start>
      <element name="foo">
         <oneOrMore>
            <element name="bar">
               <text>
                  <ega:example>My first examplotron.</ega:example>
               </text>
            </element>
         </oneOrMore>
         <ega:skipped>
            <bar xmlns="">Hello world!</bar>
         </ega:skipped>
      </element>
   </start>
</grammar>

Examplotron has seen that several "bar" elements have been defined in sequence and interpreted this as a sign that one or more occurrences of "bar" were allowed. He has used the first instance of the "bar" element as a definition of its content and skipped the other instances.

Note that the two "bar" elements have to be defined in sequence to trigger this feature and that inserting an element between them (occurrences-non-seq.eg):

<?xml version="1.0" encoding="UTF-8"?>
<foo>
	<bar>My first examplotron.</bar>
	<baz/>
	<bar>Hello world!</bar>
</foo>

Would kill this magic (occurrences-non-seq.rng):

<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:ega="http://examplotron.org/annotations/"
         xmlns:sch="http://www.ascc.net/xml/schematron"
         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
   <start>
      <element name="foo">
         <element name="bar">
            <text>
               <ega:example>My first examplotron.</ega:example>
            </text>
         </element>
         <element name="baz">
            <empty/>
         </element>
         <element name="bar">
            <text>
               <ega:example>Hello world!</ega:example>
            </text>
         </element>
      </element>
   </start>
</grammar>

Open issue: Should we remove this rule for interleave and mixed contents?

5.4. More control over occurrences

It is also possible to override the definition of the occurrences (examplotron3.xml):

<?xml version="1.0" encoding="UTF-8"?>
<foo xmlns:eg="http://examplotron.org/0/">
	<bar eg:occurs="+">Hello world</bar>
	<!-- eg:occurs could also have been set to "*", "." or "?" -->
</foo>

The value of the eg:occurs attributes can be "*" (0 or more), "+" (1 or more), "." (exactly one), "?" (0 or 1) or '-' (no occurrence) and defined the number of occurrences of the element (examplotron3.rng):

<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:ega="http://examplotron.org/annotations/"
         xmlns:sch="http://www.ascc.net/xml/schematron"
         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
   <start>
      <element name="foo"><!-- eg:occurs could also have been set to "*", "." or "?" -->
         <oneOrMore>
            <element name="bar">
               <text>
                  <ega:example>Hello world</ega:example>
               </text>
            </element>
         </oneOrMore>
      </element>
   </start>
</grammar>

Note that using a "eg:occurs" attribute has the same effect on adjacent definitions of the same element than the insertion of an element with another name, (occurences-over.eg):

<?xml version="1.0" encoding="UTF-8"?>
<foo xmlns:eg="http://examplotron.org/0/">
	<bar>My first examplotron.</bar>
	<bar eg:occurs=".">This declaration "isolates" the previous one from the next one</bar>
	<bar>Hello world!</bar>
	<bar>This new declaration has the effect that the previous one will be considered as "oneOrMore".</bar>
</foo>

Will give (occurences-over.rng):

<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:ega="http://examplotron.org/annotations/"
         xmlns:sch="http://www.ascc.net/xml/schematron"
         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
   <start>
      <element name="foo">
         <element name="bar">
            <text>
               <ega:example>My first examplotron.</ega:example>
            </text>
         </element>
         <element name="bar">
            <text>
               <ega:example>This declaration "isolates" the previous one from the next one</ega:example>
            </text>
         </element>
         <oneOrMore>
            <element name="bar">
               <text>
                  <ega:example>Hello world!</ega:example>
               </text>
            </element>
         </oneOrMore>
         <ega:skipped>
            <bar xmlns="" xmlns:eg="http://examplotron.org/0/">This new declaration has the effect that the previous one will be considered as "oneOrMore".</bar>
         </ega:skipped>
      </element>
   </start>
</grammar>

The "-" can be used to skip a definition which is then considered as an annotation. This is usefull especially to overide the effect of the previous rule when a "zeroOrMore" has been forced. For instance, to specify that we want "zeroOrMore" element "bar" while keeping two instances of them in the schema (occurences-ann.eg):

<?xml version="1.0" encoding="UTF-8"?>
<foo xmlns:eg="http://examplotron.org/0/">
	<bar eg:occurs="*">My first examplotron.</bar>
	<bar eg:occurs="-">Hello world!</bar>
</foo>

Will give (occurences-ann.rng):

<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:ega="http://examplotron.org/annotations/"
         xmlns:sch="http://www.ascc.net/xml/schematron"
         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
   <start>
      <element name="foo">
         <zeroOrMore>
            <element name="bar">
               <text>
                  <ega:example>My first examplotron.</ega:example>
               </text>
            </element>
         </zeroOrMore>
         <ega:annotation>
            <bar xmlns="" xmlns:eg="http://examplotron.org/0/" eg:occurs="-">Hello world!</bar>
         </ega:annotation>
      </element>
   </start>
</grammar>

This feature can also be used to add annotations as elements to a schema.

5.5. Namespaces

Examplotron does support namespaces without any known restriction using namespaces in the examplotron documents as in any instance document (examplotron4.xml):

<?xml version="1.0" encoding="UTF-8"?>
<foo xmlns:eg="http://examplotron.org/0/"
     xmlns:bar="http://http://examplotron.org/otherns/">
	<bar:bar eg:occurs="+">Hello world</bar:bar>
</foo>

is straightforwardly translated into (examplotron4.rng):

<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:ega="http://examplotron.org/annotations/"
         xmlns:sch="http://www.ascc.net/xml/schematron"
         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
   <start>
      <element name="foo">
         <oneOrMore>
            <element name="bar" ns="http://http://examplotron.org/otherns/">
               <text>
                  <ega:example>Hello world</ega:example>
               </text>
            </element>
         </oneOrMore>
      </element>
   </start>
</grammar>

5.6. Mixed Content

When children elements and text nodes with non whitespace characters are found in an element, the content model is assumed to be mixed as defined by Relax NG (ie text nodes may appear everywhere between elements and the children elements may appear in any order). This schema (mixed.eg):

<?xml version="1.0" encoding="UTF-8"?>
<p>This paragraph is <b>mixed content</b> as defined by <a href="http://relaxng.org">Relax NG</a>
</p>

Would be translated into:

<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:ega="http://examplotron.org/annotations/"
         xmlns:sch="http://www.ascc.net/xml/schematron"
         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
   <start>
      <element name="p">
         <mixed>
            <ega:example>This paragraph is </ega:example>
            <element name="b">
               <text>
                  <ega:example>mixed content</ega:example>
               </text>
            </element>
            <ega:example> as defined by </ega:example>
            <element name="a">
               <optional>
                  <attribute name="href">
                     <ega:example href="http://relaxng.org"/>
                  </attribute>
               </optional>
               <text>
                  <ega:example>Relax NG</ega:example>
               </text>
            </element>
         </mixed>
      </element>
   </start>
</grammar>

5.7. Iconic Datatypes

Examplotron does its best to guess the simple types found in elements and attributes. The following W3C XML Schema datatypes are supported:

Note that Examplotron implementations do not check the values of the numeric fields of ISO 8601 date and time formats and will for instance interpret "9999-99-99+99:99" as a date. This feature is defined to facilitate the job of both schema authors and Examplotron validators: even though "9999-99-99+99:99" is not a valid date, it "looks" like a date and that should be enough for the iconic nature of Examplotron.

Most of the time, these inferences give a pretty accurate result and the following schema (iconic-types.eg):

<?xml version="1.0" encoding="UTF-8"?>
<order no="1234" date="2003-02-01">
	<quantity>1</quantity>
	<ref>AZERTY</ref>
	<item>Tee shirt</item>
	<price unit="USD">10.</price>
</order>

gives (iconic-types.rng):

<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:ega="http://examplotron.org/annotations/"
         xmlns:sch="http://www.ascc.net/xml/schematron"
         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
   <start>
      <element name="order">
         <optional>
            <attribute name="no">
               <data type="integer">
                  <ega:example no="1234"/>
               </data>
            </attribute>
         </optional>
         <optional>
            <attribute name="date">
               <data type="date">
                  <ega:example date="2003-02-01"/>
               </data>
            </attribute>
         </optional>
         <element name="quantity">
            <data type="integer">
               <ega:example>1</ega:example>
            </data>
         </element>
         <element name="ref">
            <text>
               <ega:example>AZERTY</ega:example>
            </text>
         </element>
         <element name="item">
            <text>
               <ega:example>Tee shirt</ega:example>
            </text>
         </element>
         <element name="price">
            <optional>
               <attribute name="unit">
                  <ega:example unit="USD"/>
               </attribute>
            </optional>
            <data type="decimal">
               <ega:example>10.</ega:example>
            </data>
         </element>
      </element>
   </start>
</grammar>

Text nodes which do not obviously belong to one of the supported datatypes are translated as "text" patterns and this is also the case for any text pattern (whatever guesses could be made) appearing in an interleave (or mixed) content model (the latest is necessary to match a restriction of Relax NG).

5.8. More control over content models

We have seen how to specify text only, unordered elements only and mixed content models through the "iconic" features of Examplotron. The "eg:content" attribute gives full control over the content model and overides the guesses done by Examplotron from the content model of the schema. This attribute can take the values:

For instance, to request that the schema above does not enforce the relative order of the children elements of the "order" element, "eg:content" should be set to "eg:interleave", such as (interleave.eg):

<?xml version="1.0" encoding="UTF-8"?>
<order xmlns:eg="http://examplotron.org/0/"
       no="1234"
       date="2003-02-01"
       eg:content="eg:interleave">
	<quantity>1</quantity>
	<ref>AZERTY</ref>
	<item>Tee shirt</item>
	<price unit="USD">10.</price>
</order>

gives (interleave.rng):

<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:ega="http://examplotron.org/annotations/"
         xmlns:sch="http://www.ascc.net/xml/schematron"
         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
   <start>
      <element name="order">
         <interleave>
            <optional>
               <attribute name="no">
                  <data type="integer">
                     <ega:example no="1234"/>
                  </data>
               </attribute>
            </optional>
            <optional>
               <attribute name="date">
                  <data type="date">
                     <ega:example date="2003-02-01"/>
                  </data>
               </attribute>
            </optional>
            <element name="quantity">
               <data type="integer">
                  <ega:example>1</ega:example>
               </data>
            </element>
            <element name="ref">
               <text>
                  <ega:example>AZERTY</ega:example>
               </text>
            </element>
            <element name="item">
               <text>
                  <ega:example>Tee shirt</ega:example>
               </text>
            </element>
            <element name="price">
               <optional>
                  <attribute name="unit">
                     <ega:example unit="USD"/>
                  </attribute>
               </optional>
               <data type="decimal">
                  <ega:example>10.</ega:example>
               </data>
            </element>
         </interleave>
      </element>
   </start>
</grammar>

"eg:mixed" can be used to force a content model to be mixed even if it doesn't contain any text node in its schema, for instance (mixed-forced.eg):

<?xml version="1.0" encoding="UTF-8"?>
<p xmlns:eg="http://examplotron.org/0/" eg:content="eg:mixed">
	<b eg:occurs="*">Bold text</b>
	<a href="uri" eg:occurs="*">Hypertext link</a>
</p>

gives (mixed-forced.rng):

<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:ega="http://examplotron.org/annotations/"
         xmlns:sch="http://www.ascc.net/xml/schematron"
         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
   <start>
      <element name="p">
         <mixed>
            <zeroOrMore>
               <element name="b">
                  <text>
                     <ega:example>Bold text</ega:example>
                  </text>
               </element>
            </zeroOrMore>
            <zeroOrMore>
               <element name="a">
                  <optional>
                     <attribute name="href">
                        <ega:example href="uri"/>
                     </attribute>
                  </optional>
                  <text>
                     <ega:example>Hypertext link</ega:example>
                  </text>
               </element>
            </zeroOrMore>
         </mixed>
      </element>
   </start>
</grammar>

"eg:group" may be used to force a mixed content to be ordered. For instance, even if it is often considered to be a bad practice, one might want to define (group.eg):

<?xml version="1.0" encoding="UTF-8"?>
<price xmlns:eg="http://examplotron.org/0/" eg:content="eg:group">
	<currency>Euro</currency>25	
</price>

and impose that the "currency" element precedes the text node. This would give (group.rng):

<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:ega="http://examplotron.org/annotations/"
         xmlns:sch="http://www.ascc.net/xml/schematron"
         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
   <start>
      <element name="price">
         <element name="currency">
            <text>
               <ega:example>Euro</ega:example>
            </text>
         </element>
         <text>
            <ega:example>25	
</ega:example>
         </text>
      </element>
   </start>
</grammar>

Note that in this case, the text node cannot be defined as a "data" and its datatype cannot be enforced (this is a restriction of Relax NG).

The last Relax NG compositors (choice) has not been implemented since it doesn't seem very useful as a compositor for the whole content of an element.

Note that the prefix "eg" is reserved for this usage and should be used even if the namespace for Examplotron had been assigned to another prefix. The previous schema is thus strictly equivalent to the following one (mixed-forced-ns.eg):

<?xml version="1.0" encoding="UTF-8"?>
<p xmlns:foo="http://examplotron.org/0/" foo:content="eg:mixed">
	<b>bold</b>
	<a href="uri">link</a>
</p>

5.9. More control over simple types

As for content models, the assumption done by Examplotron for simple types may be overidden. For elements, simple types may be specified using the eg:content attribute. There is no risk of confusion since the usage of eg:content to specify a compositor implies that the element has children elements while the usage to define a simple type implies that the element is text only. Furthermore, the semantic of defining a specificity of the content is the same for both usages and using two different attributes would have created a risk of incoherencies between their usages.

The datatype is defined using a prefixed name and in addition to "eg", a new prefixes is reserved and may be used without namespace declarations: "xsd" identifies the W3C XML Schema datatypes.

When a datatype is specified for an element, the content of the element is skipped.

This feature can be used to give more restictive type declarations (for instance xs:byte instead of integer) and also for schemas in which documentation is placed in the elements. For instance (forced-types.eg):

<?xml version="1.0" encoding="UTF-8"?>
<order xmlns:eg="http://examplotron.org/0/"
       no="1234"
       date="2003-02-01"
       eg:content="eg:group">
	<quantity eg:content="xsd:nonNegativeInteger">
		Number of ordered items
	</quantity>
	<ref eg:content="xsd:token">
		Item's reference (see the <a href="ref-list.html">reference list</a>).
	</ref>
	<item eg:content="xsd:token">
		Description of the item
	</item>
	<price unit="USD" eg:content="xsd:decimal">
		Unit price of the item
	</price>
</order>

Which would give (forced-types.rng):

<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:ega="http://examplotron.org/annotations/"
         xmlns:sch="http://www.ascc.net/xml/schematron"
         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
   <start>
      <element name="order">
         <optional>
            <attribute name="no">
               <data type="integer">
                  <ega:example no="1234"/>
               </data>
            </attribute>
         </optional>
         <optional>
            <attribute name="date">
               <data type="date">
                  <ega:example date="2003-02-01"/>
               </data>
            </attribute>
         </optional>
         <element name="quantity">
            <ega:skipped>
		Number of ordered items
	</ega:skipped>
            <data type="nonNegativeInteger"/>
         </element>
         <element name="ref">
            <ega:skipped>
		Item's reference (see the <a xmlns="" xmlns:eg="http://examplotron.org/0/" href="ref-list.html">reference list</a>).
	</ega:skipped>
            <data type="token"/>
         </element>
         <element name="item">
            <ega:skipped>
		Description of the item
	</ega:skipped>
            <data type="token"/>
         </element>
         <element name="price">
            <optional>
               <attribute name="unit">
                  <ega:example unit="USD"/>
               </attribute>
            </optional>
            <ega:skipped>
		Unit price of the item
	</ega:skipped>
            <data type="decimal"/>
         </element>
      </element>
   </start>
</grammar>

Note that the content which is skipped is now embedded in a "ega:skipped" annotation instead of a "ega:example" which is reserved for content having be used for inferencing a model.

To force a type for an attribute, we need to use a specific syntax since attributes can't hold "eg:content" attributes... The trick here is to include the datatype in curly braces ({}). For instance (forced-types-att.eg):

<?xml version="1.0" encoding="UTF-8"?>
<order no="{xsd:unsignedInt}" date="2003-02-01">
	<quantity>1</quantity>
	<ref>AZERTY</ref>
	<item>Tee shirt</item>
	<price unit="{xsd:NMTOKEN}">10.</price>
</order>

Which would give (forced-types-att.rng):

<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:ega="http://examplotron.org/annotations/"
         xmlns:sch="http://www.ascc.net/xml/schematron"
         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
   <start>
      <element name="order">
         <optional>
            <attribute name="no">
               <data type="unsignedInt"/>
            </attribute>
         </optional>
         <optional>
            <attribute name="date">
               <data type="date">
                  <ega:example date="2003-02-01"/>
               </data>
            </attribute>
         </optional>
         <element name="quantity">
            <data type="integer">
               <ega:example>1</ega:example>
            </data>
         </element>
         <element name="ref">
            <text>
               <ega:example>AZERTY</ega:example>
            </text>
         </element>
         <element name="item">
            <text>
               <ega:example>Tee shirt</ega:example>
            </text>
         </element>
         <element name="price">
            <optional>
               <attribute name="unit">
                  <data type="NMTOKEN"/>
               </attribute>
            </optional>
            <data type="decimal">
               <ega:example>10.</ega:example>
            </data>
         </element>
      </element>
   </start>
</grammar>

Datatypes from the Relax NG DTD compatibility library (ie ID, IDREF and IDREFS) can also be used using a third "magic prefix", "dtd". . For instance (forced-types-att-dtd.eg):

<?xml version="1.0" encoding="UTF-8"?>
<library>
	<book id="{dtd:ID}">
		  <title>Being a Dog Is a Full-Time Job</title>
		  <author-refs idref="{dtd:IDREFS}"/>
	</book>
	<author id="{dtd:ID}">
		  <name>Charles M Schulz</name>
	</author>
</library>

Which would give (forced-types-att-dtd.rng):

<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:ega="http://examplotron.org/annotations/"
         xmlns:sch="http://www.ascc.net/xml/schematron"
         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
   <start>
      <element name="library">
         <element name="book">
            <optional>
               <attribute name="id">
                  <data type="ID"
                  datatypeLibrary="http://relaxng.org/ns/compatibility/datatypes/1.0"/>
               </attribute>
            </optional>
            <element name="title">
               <text>
                  <ega:example>Being a Dog Is a Full-Time Job</ega:example>
               </text>
            </element>
            <element name="author-refs">
               <optional>
                  <attribute name="idref">
                     <data type="IDREFS"
                    datatypeLibrary="http://relaxng.org/ns/compatibility/datatypes/1.0"/>
                  </attribute>
               </optional>
            </element>
         </element>
         <element name="author">
            <optional>
               <attribute name="id">
                  <data type="ID"
                  datatypeLibrary="http://relaxng.org/ns/compatibility/datatypes/1.0"/>
               </attribute>
            </optional>
            <element name="name">
               <text>
                  <ega:example>Charles M Schulz</ega:example>
               </text>
            </element>
         </element>
      </element>
   </start>
</grammar>

Other libraries may be used as well but a prefix need to be declared for them (forced-types-other.eg):

<?xml version="1.0" encoding="UTF-8"?>
<order xmlns:py="http://namespaces.xmlschemata.org/xvif/python-types"
       xmlns:eg="http://examplotron.org/0/"
       no="{py:int}"
       date="2003-02-01">
	<quantity eg:content="py:int">1</quantity>
	<ref>AZERTY</ref>
	<item>Tee shirt</item>
	<price unit="{py:float}">10.</price>
</order>

Which would give (forced-types-other.rng):

<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:ega="http://examplotron.org/annotations/"
         xmlns:sch="http://www.ascc.net/xml/schematron"
         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
   <start>
      <element name="order">
         <optional>
            <attribute name="no">
               <data xmlns:py="http://namespaces.xmlschemata.org/xvif/python-types"
                type="py:int"/>
            </attribute>
         </optional>
         <optional>
            <attribute name="date">
               <data type="date">
                  <ega:example date="2003-02-01"/>
               </data>
            </attribute>
         </optional>
         <element name="quantity">
            <ega:skipped>1</ega:skipped>
            <data xmlns:py="http://namespaces.xmlschemata.org/xvif/python-types"
              type="py:int"/>
         </element>
         <element name="ref">
            <text>
               <ega:example>AZERTY</ega:example>
            </text>
         </element>
         <element name="item">
            <text>
               <ega:example>Tee shirt</ega:example>
            </text>
         </element>
         <element name="price">
            <optional>
               <attribute name="unit">
                  <data xmlns:py="http://namespaces.xmlschemata.org/xvif/python-types"
                  type="py:float"/>
               </attribute>
            </optional>
            <data type="decimal">
               <ega:example>10.</ega:example>
            </data>
         </element>
      </element>
   </start>
</grammar>

5.10. More on attributes

Up to now, we've seen less control over attributes and this primarly due to the fact that XML attributes can't have a structure which would embed all the annotations we need to control them in a schema. To solve this, Examplotron uses the usual workaround that changes attributes into elements and attributes can also be defined using a "eg:attribute" element (att-occurs.eg):

<?xml version="1.0" encoding="UTF-8"?>
<foo xmlns:eg="http://examplotron.org/0/">
	<eg:attribute name="bar">1</eg:attribute>
</foo>

Which is translated into (att-occurs.rng):

<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:ega="http://examplotron.org/annotations/"
         xmlns:sch="http://www.ascc.net/xml/schematron"
         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
   <start>
      <element name="foo">
         <attribute name="bar">
            <data type="integer">
               <ega:example>1</ega:example>
            </data>
         </attribute>
      </element>
   </start>
</grammar>

Note that by default, attributes defined using "eg:attribute" are mandatory. This is because one of the main reasons for defining attributes using "eg:attribute" is to define mandatory attributes. The number of occurrences and datatype could be overriden using "eg:occurs" and "eg:content" like it is the case for elements.

5.11. Flat schemas

Let's take an example from W3C XML Schema part 0 to illustrate this point (po.eg):

<?xml version="1.0" encoding="UTF-8"?>
<purchaseOrder orderDate="1999-10-20">
    <shipTo country="US">
        <name>Alice Smith</name>
        <street>123 Maple Street</street>
        <city>Mill Valley</city>
        <state>CA</state>
        <zip>90952</zip>
    </shipTo>
    <billTo country="US">
        <name>Robert Smith</name>
        <street>8 Oak Avenue</street>
        <city>Old Town</city>
        <state>PA</state>
        <zip>95819</zip>
    </billTo>
    <comment>Hurry, my lawn is going wild!</comment>
    <items>
        <item partNum="872-AA">
            <productName>Lawnmower</productName>
            <quantity>1</quantity>
            <USPrice>148.95</USPrice>
            <comment>Confirm this is electric</comment>
        </item>
        <item partNum="926-AA">
            <productName>Baby Monitor</productName>
            <quantity>1</quantity>
            <USPrice>39.98</USPrice>
            <shipDate>1999-05-21</shipDate>
        </item>
    </items>
</purchaseOrder>

This schema can be used straight away and gives (po.rng):

<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:ega="http://examplotron.org/annotations/"
         xmlns:sch="http://www.ascc.net/xml/schematron"
         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
   <start>
      <element name="purchaseOrder">
         <optional>
            <attribute name="orderDate">
               <data type="date">
                  <ega:example orderDate="1999-10-20"/>
               </data>
            </attribute>
         </optional>
         <element name="shipTo">
            <optional>
               <attribute name="country">
                  <ega:example country="US"/>
               </attribute>
            </optional>
            <element name="name">
               <text>
                  <ega:example>Alice Smith</ega:example>
               </text>
            </element>
            <element name="street">
               <text>
                  <ega:example>123 Maple Street</ega:example>
               </text>
            </element>
            <element name="city">
               <text>
                  <ega:example>Mill Valley</ega:example>
               </text>
            </element>
            <element name="state">
               <text>
                  <ega:example>CA</ega:example>
               </text>
            </element>
            <element name="zip">
               <data type="integer">
                  <ega:example>90952</ega:example>
               </data>
            </element>
         </element>
         <element name="billTo">
            <optional>
               <attribute name="country">
                  <ega:example country="US"/>
               </attribute>
            </optional>
            <element name="name">
               <text>
                  <ega:example>Robert Smith</ega:example>
               </text>
            </element>
            <element name="street">
               <text>
                  <ega:example>8 Oak Avenue</ega:example>
               </text>
            </element>
            <element name="city">
               <text>
                  <ega:example>Old Town</ega:example>
               </text>
            </element>
            <element name="state">
               <text>
                  <ega:example>PA</ega:example>
               </text>
            </element>
            <element name="zip">
               <data type="integer">
                  <ega:example>95819</ega:example>
               </data>
            </element>
         </element>
         <element name="comment">
            <text>
               <ega:example>Hurry, my lawn is going wild!</ega:example>
            </text>
         </element>
         <element name="items">
            <oneOrMore>
               <element name="item">
                  <optional>
                     <attribute name="partNum">
                        <ega:example partNum="872-AA"/>
                     </attribute>
                  </optional>
                  <element name="productName">
                     <text>
                        <ega:example>Lawnmower</ega:example>
                     </text>
                  </element>
                  <element name="quantity">
                     <data type="integer">
                        <ega:example>1</ega:example>
                     </data>
                  </element>
                  <element name="USPrice">
                     <data type="decimal">
                        <ega:example>148.95</ega:example>
                     </data>
                  </element>
                  <element name="comment">
                     <text>
                        <ega:example>Confirm this is electric</ega:example>
                     </text>
                  </element>
               </element>
            </oneOrMore>
            <ega:skipped>
               <item xmlns="" partNum="926-AA">
                  <productName>Baby Monitor</productName>
                  <quantity>1</quantity>
                  <USPrice>39.98</USPrice>
                  <shipDate>1999-05-21</shipDate>
               </item>
            </ega:skipped>
         </element>
      </element>
   </start>
</grammar>

However, this doesn't show the similarity between "billTo" and "shipTo" which have the same structure. To do so, we can use a new attribute "eg:define" in one of the instances of this structure and use "eg:content" to reference this definition in the other instances (po-id.eg):

<?xml version="1.0" encoding="UTF-8"?>
<purchaseOrder xmlns:eg="http://examplotron.org/0/" orderDate="1999-10-20">
    <shipTo country="US" eg:define="address">
        <name>Alice Smith</name>
        <street>123 Maple Street</street>
        <city>Mill Valley</city>
        <state>CA</state>
        <zip>90952</zip>
    </shipTo>
    <billTo country="US" eg:content="address">
        <name>Robert Smith</name>
        <street>8 Oak Avenue</street>
        <city>Old Town</city>
        <state>PA</state>
        <zip>95819</zip>
    </billTo>
    <comment>Hurry, my lawn is going wild!</comment>
    <items>
        <item partNum="872-AA">
            <productName>Lawnmower</productName>
            <quantity>1</quantity>
            <USPrice>148.95</USPrice>
            <comment>Confirm this is electric</comment>
        </item>
        <item partNum="926-AA">
            <productName>Baby Monitor</productName>
            <quantity>1</quantity>
            <USPrice>39.98</USPrice>
            <shipDate>1999-05-21</shipDate>
        </item>
    </items>
</purchaseOrder>

This will generate a named pattern with the definition and references where needed (po-id.rng):

<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:ega="http://examplotron.org/annotations/"
         xmlns:sch="http://www.ascc.net/xml/schematron"
         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
   <start>
      <element name="purchaseOrder">
         <optional>
            <attribute name="orderDate">
               <data type="date">
                  <ega:example orderDate="1999-10-20"/>
               </data>
            </attribute>
         </optional>
         <element name="shipTo">
            <ref name="address" ega:def="true"/>
         </element>
         <element name="billTo">
            <ref name="address">
               <ega:skipped>
                  <billTo xmlns=""
                    xmlns:eg="http://examplotron.org/0/"
                    country="US"
                    eg:content="address">
                     <name>Robert Smith</name>
                     <street>8 Oak Avenue</street>
                     <city>Old Town</city>
                     <state>PA</state>
                     <zip>95819</zip>
                  </billTo>
               </ega:skipped>
            </ref>
         </element>
         <element name="comment">
            <text>
               <ega:example>Hurry, my lawn is going wild!</ega:example>
            </text>
         </element>
         <element name="items">
            <oneOrMore>
               <element name="item">
                  <optional>
                     <attribute name="partNum">
                        <ega:example partNum="872-AA"/>
                     </attribute>
                  </optional>
                  <element name="productName">
                     <text>
                        <ega:example>Lawnmower</ega:example>
                     </text>
                  </element>
                  <element name="quantity">
                     <data type="integer">
                        <ega:example>1</ega:example>
                     </data>
                  </element>
                  <element name="USPrice">
                     <data type="decimal">
                        <ega:example>148.95</ega:example>
                     </data>
                  </element>
                  <element name="comment">
                     <text>
                        <ega:example>Confirm this is electric</ega:example>
                     </text>
                  </element>
               </element>
            </oneOrMore>
            <ega:skipped>
               <item xmlns="" xmlns:eg="http://examplotron.org/0/" partNum="926-AA">
                  <productName>Baby Monitor</productName>
                  <quantity>1</quantity>
                  <USPrice>39.98</USPrice>
                  <shipDate>1999-05-21</shipDate>
               </item>
            </ega:skipped>
         </element>
      </element>
   </start>
   <define name="address">
      <optional>
         <attribute name="country">
            <ega:example country="US"/>
         </attribute>
      </optional>
      <element name="name">
         <text>
            <ega:example>Alice Smith</ega:example>
         </text>
      </element>
      <element name="street">
         <text>
            <ega:example>123 Maple Street</ega:example>
         </text>
      </element>
      <element name="city">
         <text>
            <ega:example>Mill Valley</ega:example>
         </text>
      </element>
      <element name="state">
         <text>
            <ega:example>CA</ega:example>
         </text>
      </element>
      <element name="zip">
         <data type="integer">
            <ega:example>90952</ega:example>
         </data>
      </element>
   </define>
</grammar>

This mechanism can be used without reference to force the definition of a named pattern for the content of an element or attribute and we could ask that the "item" and "purchaseOrder" elements are described as named patterns (po-ct.eg):

<?xml version="1.0" encoding="UTF-8"?>
<purchaseOrder xmlns:eg="http://examplotron.org/0/"
               orderDate="1999-10-20"
               eg:define="po">
    <shipTo country="US" eg:define="address">
        <name>Alice Smith</name>
        <street>123 Maple Street</street>
        <city>Mill Valley</city>
        <state>CA</state>
        <zip>90952</zip>
    </shipTo>
    <billTo country="US" eg:content="address">
        <name>Robert Smith</name>
        <street>8 Oak Avenue</street>
        <city>Old Town</city>
        <state>PA</state>
        <zip>95819</zip>
    </billTo>
    <comment>Hurry, my lawn is going wild!</comment>
    <items>
        <item partNum="872-AA" eg:define="item">
            <productName>Lawnmower</productName>
            <quantity>1</quantity>
            <USPrice>148.95</USPrice>
            <comment>Confirm this is electric</comment>
        </item>
        <item partNum="926-AA">
            <productName>Baby Monitor</productName>
            <quantity>1</quantity>
            <USPrice>39.98</USPrice>
            <shipDate>1999-05-21</shipDate>
        </item>
    </items>
</purchaseOrder>

Which will give (po-ct.eg):

<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:ega="http://examplotron.org/annotations/"
         xmlns:sch="http://www.ascc.net/xml/schematron"
         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
   <start>
      <element name="purchaseOrder">
         <ref name="po" ega:def="true"/>
      </element>
   </start>
   <define name="po">
      <optional>
         <attribute name="orderDate">
            <data type="date">
               <ega:example orderDate="1999-10-20"/>
            </data>
         </attribute>
      </optional>
      <element name="shipTo">
         <ref name="address" ega:def="true"/>
      </element>
      <element name="billTo">
         <ref name="address">
            <ega:skipped>
               <billTo xmlns=""
                  xmlns:eg="http://examplotron.org/0/"
                  country="US"
                  eg:content="address">
                  <name>Robert Smith</name>
                  <street>8 Oak Avenue</street>
                  <city>Old Town</city>
                  <state>PA</state>
                  <zip>95819</zip>
               </billTo>
            </ega:skipped>
         </ref>
      </element>
      <element name="comment">
         <text>
            <ega:example>Hurry, my lawn is going wild!</ega:example>
         </text>
      </element>
      <element name="items">
         <oneOrMore>
            <element name="item">
               <ref name="item" ega:def="true"/>
            </element>
         </oneOrMore>
         <ega:skipped>
            <item xmlns="" xmlns:eg="http://examplotron.org/0/" partNum="926-AA">
               <productName>Baby Monitor</productName>
               <quantity>1</quantity>
               <USPrice>39.98</USPrice>
               <shipDate>1999-05-21</shipDate>
            </item>
         </ega:skipped>
      </element>
   </define>
   <define name="address">
      <optional>
         <attribute name="country">
            <ega:example country="US"/>
         </attribute>
      </optional>
      <element name="name">
         <text>
            <ega:example>Alice Smith</ega:example>
         </text>
      </element>
      <element name="street">
         <text>
            <ega:example>123 Maple Street</ega:example>
         </text>
      </element>
      <element name="city">
         <text>
            <ega:example>Mill Valley</ega:example>
         </text>
      </element>
      <element name="state">
         <text>
            <ega:example>CA</ega:example>
         </text>
      </element>
      <element name="zip">
         <data type="integer">
            <ega:example>90952</ega:example>
         </data>
      </element>
   </define>
   <define name="item">
      <optional>
         <attribute name="partNum">
            <ega:example partNum="872-AA"/>
         </attribute>
      </optional>
      <element name="productName">
         <text>
            <ega:example>Lawnmower</ega:example>
         </text>
      </element>
      <element name="quantity">
         <data type="integer">
            <ega:example>1</ega:example>
         </data>
      </element>
      <element name="USPrice">
         <data type="decimal">
            <ega:example>148.95</ega:example>
         </data>
      </element>
      <element name="comment">
         <text>
            <ega:example>Confirm this is electric</ega:example>
         </text>
      </element>
   </define>
</grammar>

5.12. Assertions

In order to describe more complex rules, it is possible to define assertions (i.e. statements that need to be met) as XPath expressions using "eg:assert" attributes (examplotron5.xml):

<?xml version="1.0" encoding="UTF-8"?>
<foo xmlns:eg="http://examplotron.org/0/" eg:assert="sum(percent)=100">
<!-- The sum of the values of the "percent" element needs to be equal to 100 -->
	<percent eg:occurs="+">100</percent>
</foo>

The implementation of this feature is optional and may may vary depending on the architecture of the implementation. One of the possibilities is to generate Schematron embedded assertions as supported by Sun's MSV (examplotron5.rng):

<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:ega="http://examplotron.org/annotations/"
         xmlns:sch="http://www.ascc.net/xml/schematron"
         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
   <start>
      <element name="foo"><!-- The sum of the values of the "percent" element needs to be equal to 100 -->
         <sch:assert xmlns:eg="http://examplotron.org/0/" test="sum(percent)=100"/>
         <oneOrMore>
            <element name="percent">
               <data type="integer">
                  <ega:example>100</ega:example>
               </data>
            </element>
         </oneOrMore>
      </element>
   </start>
</grammar>

Assertions can be used without restriction on document using namespaces, but please remember that XPath expressions do not support default namespaces (examplotron6.xml):

<?xml version="1.0" encoding="UTF-8"?>
<foo:foo xmlns:eg="http://examplotron.org/0/"
         xmlns:foo="http://examplotron/otherns/foo"
         xmlns:bar="http://examplotron/otherns/bar"
         eg:assert="sum(bar:percent)=100">
	<bar:percent eg:occurs="+">100</bar:percent>
</foo:foo>

To deal with possible redefinitions of namespace prefixes, the compiler copies all the namespaces nodes found in the element where the assertion is found in the template (examplotron6.rng):

<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:ega="http://examplotron.org/annotations/"
         xmlns:sch="http://www.ascc.net/xml/schematron"
         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
   <start>
      <element name="foo" ns="http://examplotron/otherns/foo">
         <sch:assert xmlns:eg="http://examplotron.org/0/"
                  xmlns:foo="http://examplotron/otherns/foo"
                  xmlns:bar="http://examplotron/otherns/bar"
                  test="sum(bar:percent)=100"/>
         <oneOrMore>
            <element name="percent" ns="http://examplotron/otherns/bar">
               <data type="integer">
                  <ega:example>100</ega:example>
               </data>
            </element>
         </oneOrMore>
      </element>
   </start>
</grammar>

Many thanks to David Carlisle for this tip.

5.13. Default values

Default values are an optional feature of RELAX NG described in the RELAX NG DTD Compatibility

.

This feature is neither widely used nor widely implemented but John Cowan gave a very convincing use case for supporting them in Examplotron at Balisage 2013.

Default values in Examplotron are enclosed in square brackets (default1.eg):

<?xml version="1.0" encoding="UTF-8"?>
<foo bar="[my default value]"/>

Gives (default1.rng):

<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:ega="http://examplotron.org/annotations/"
         xmlns:sch="http://www.ascc.net/xml/schematron"
         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
   <start>
      <element name="foo">
         <optional>
            <attribute xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
                   name="bar"
                   a:defaultValue="my default value">
               <ega:example>my default value</ega:example>
            </attribute>
         </optional>
      </element>
   </start>
</grammar>

Type detection works as usual with default values and (default2.eg):

<?xml version="1.0" encoding="UTF-8"?>
<defaults integer="[1]"
          decimal="[-120.4]"
          double="[1.8E10]"
          date="[2013-08-21]"
          dateTime="[2013-08-21T19:04:32]"
          time="[19:04:48]"
          boolean="[true]"/>

Gives (default2.rng):

<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:ega="http://examplotron.org/annotations/"
         xmlns:sch="http://www.ascc.net/xml/schematron"
         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
   <start>
      <element name="defaults">
         <optional>
            <attribute xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
                   name="integer"
                   a:defaultValue="1">
               <data type="integer">
                  <ega:example>1</ega:example>
               </data>
            </attribute>
         </optional>
         <optional>
            <attribute xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
                   name="decimal"
                   a:defaultValue="-120.4">
               <data type="decimal">
                  <ega:example>-120.4</ega:example>
               </data>
            </attribute>
         </optional>
         <optional>
            <attribute xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
                   name="double"
                   a:defaultValue="1.8E10">
               <data type="double">
                  <ega:example>1.8E10</ega:example>
               </data>
            </attribute>
         </optional>
         <optional>
            <attribute xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
                   name="date"
                   a:defaultValue="2013-08-21">
               <data type="date">
                  <ega:example>2013-08-21</ega:example>
               </data>
            </attribute>
         </optional>
         <optional>
            <attribute xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
                   name="dateTime"
                   a:defaultValue="2013-08-21T19:04:32">
               <data type="dateTime">
                  <ega:example>2013-08-21T19:04:32</ega:example>
               </data>
            </attribute>
         </optional>
         <optional>
            <attribute xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
                   name="time"
                   a:defaultValue="19:04:48">
               <data type="time">
                  <ega:example>19:04:48</ega:example>
               </data>
            </attribute>
         </optional>
         <optional>
            <attribute xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
                   name="boolean"
                   a:defaultValue="true">
               <data type="boolean">
                  <ega:example>true</ega:example>
               </data>
            </attribute>
         </optional>
      </element>
   </start>
</grammar>

Default values can also be used with eg:attribut elements and (default3.eg):

<?xml version="1.0" encoding="UTF-8"?>
<defaults xmlns:eg="http://examplotron.org/0/">
    <eg:attribute name="integer">[-1]</eg:attribute>
    <eg:attribute name="decimal" eg:content="xsd:decimal">[-1]</eg:attribute>
</defaults>

Gives (default3.rng):

<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:ega="http://examplotron.org/annotations/"
         xmlns:sch="http://www.ascc.net/xml/schematron"
         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
   <start>
      <element name="defaults">
         <attribute xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
                 name="integer"
                 a:defaultValue="-1">
            <data type="integer">
               <ega:example>-1</ega:example>
            </data>
         </attribute>
         <attribute xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
                 name="decimal"
                 a:defaultValue="-1">
            <ega:skipped>[-1]</ega:skipped>
            <data type="decimal"/>
         </attribute>
      </element>
   </start>
</grammar>

More controversially, and as en experimental feature Examplotron lets you define default values on elements and (default4.eg):

<?xml version="1.0" encoding="UTF-8"?>
<use-at-your-own-risk xmlns:eg="http://examplotron.org/0/">
    <integer>[-1]</integer>
    <decimal eg:content="xsd:decimal">[-1]</decimal>
    <whatever>[A default value.]</whatever>
</use-at-your-own-risk>

Gives (default4.rng):

<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:ega="http://examplotron.org/annotations/"
         xmlns:sch="http://www.ascc.net/xml/schematron"
         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
   <start>
      <element name="use-at-your-own-risk">
         <element xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
               name="integer"
               a:defaultValue="-1">
            <data type="integer">
               <ega:example>-1</ega:example>
            </data>
         </element>
         <element xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
               name="decimal"
               a:defaultValue="-1">
            <ega:skipped>[-1]</ega:skipped>
            <data type="decimal"/>
         </element>
         <element xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
               name="whatever"
               a:defaultValue="A default value.">
            <text>
               <ega:example>A default value.</ega:example>
            </text>
         </element>
      </element>
   </start>
</grammar>

Note that the RELAX NG DTD Compatibility specification doesn't allow to define default values on elements and use this feature at your own risk!

I have mixed feelings about abusing the specification an its namespace to add a:defaultValue to element definitions. However since you can already add these attributes in RELAX NG schemas using your favorite text editor, I don't see any strong reason why Examplotron should block you if you really want to do so. Furthermore that's an important feature for John Cowan's use case...

6. Resources

Mailing list

This mailing list is for discussing issues, bugs, questions and future development of Examplotron.

To subscribe, send a mail to examplotron-request@xmlschemata.org with "subscribe" in the subject or body.

CVS repository

This CVS repository gives you access on the detailed history of the documents composing the Examplotron distribution.

Bugs and feature requests database

This database gives you access to bug and feature requests reports posted for Examplotron. Feel free to use it to post your own reports.

This documentation has been written as a RDDL document and this section will be developed to include more resources related to examplotron.

XSLT Compiler

This compiler is a XSLT transformation that compiles an examplotron schema into a XSLT transformation that can be used to validate documents that are conform to this schema.

The compilation is known to suceed with Saxon. It should be able to run the compiler using any XSLT processor, however this transformation happens to be quite challenging for the XSLT processor and problems are known with XT (transformation aborted for lack of support of the namespace axis), libxslt (bug 105116) and 4xslt (bugs 679360 and 679374). The resulting schema must use a Relax NG processor (with support for embedded Schematron rules to support eg:assert).

W3C XML Schema for examplotron

This W3C XML Schema (Proposed Recommendation, 16 March 2001) schema describes the examplotron vocabulary and can be imported in W3C XML Schema to validate examplotron schemas.

CSS Stylesheet

A CSS stylesheet borrowed from RDDL used to provide the "look-and-feel" of this document, suitable in general for RDDL documents.

CSS Stylesheet (original).

Original version of the previous CSS stylesheet on rddl.org.

XYZFind Server User's Guide

The chapter 7. of the XYZFind Server User's Guide described a schema language used by XYZFind Server that is very similar to examplotron (no longer available online).

Proposal for XSL

This early proposal for XSL proposed a syntax similar to the one used by examplotron for expressing patterns.

Relax NG

Home page of the Relax NG Oasis TC.

7. To do

I have been pleasantly surprised after a couple of hours working on examplotron that this simple tool was beginning to be useful while still very simple (or simplistic).

The current version is already a powerful tool that can be used to validate documents.

It can be used as a main validation tool, or as a complement of a more classical validation tool, for instance, to add additional requirements and constraints to existing vocabularies when an application is using a subset of a vocabulary.

This being said, the simplicity of the tools is leaving room for many applications and extensions on which your feedback is welcome:

  1. Documentation: develop the resources section.
  2. Proof of concept: write an examplotron schema for XHTML.
  3. Finish the iconic 80%.
  4. Implement the complemental 20%.
  5. Anything else ?

8. Acknowledgements

Many thanks to the many people that have given me hints, ideas or encouragements or even let me think that examplotron could be the best invention since the French baguette.

Note: the French baguette is another very simple invention made only of flour, salt, yeast and water (exactly like examplotron that is made out of XML 1.0, Namespaces in XML 1.0, XPath 1.0 and XSLT 1.0). The Englo-American sliced bread (often used in this context), involving more ingredients and postprocessing is far more complex and does obviously not belong to the same category than examplotron.

Non normative list (by chronological order): Simon St.Laurent, Edd Dumbill, John Cowan, Len Bullard, Rick Jelliffe, Evan Lenz, Dan Brickley, Jonathan Borden, David Mundie, David Carlisle, Murata Makoto, Cyril Jandia, Amelia A. Lewis, Gavin Thomas Nicol, Tim Mueller-Seydlitz, Michael Champion, Wendell Piez, Ben Weaver, ...

9. History

V0.1

  • Creation

V0.2

  • Addition of several sections (limitations, acknowledgements, history and legal)
  • Clarifications after comments through xml-dev and private mails.
  • Addition of an history section in compile.xsl
  • Creation of a W3C XML Schema for examplotron (examplotron.xsd).
  • Start to feed the resources section.

V0.3

  • Addition of eg:assert.
  • Rewrite of the history section as RDDL resources.
  • Addition of new resources.
  • Expansion of the list of acknowledgements.

V0.4

  • Addition of eg:import.
  • Addition of eg:placeHolder.
  • Restructured the document.
  • Addition of new resources.
  • Expansion of the list of acknowledgements.

V0.5

Major architectural change with constant set of features.

  • "compile.xsl" no longer generate a XSLT transformation but a Relax NG schema.
  • Repeated elements are no longer considered as choice but as a sequence of different definitions.
  • Imports need to be redefined.
  • Place holders shouldn't be needed any longer.
  • Expansion of the list of acknowledgements.

V0.6

Bug fixes

  • Add an empty pattern to empty elements (Bug #26)
  • Remove a broken link (Bug #25)
  • Add resources to bugzilla (Bug #27)

V0.7

Major release

  • Inferences (occurrences, types, ...)
  • Type control
  • eg:attribute
  • @eg:define
  • And much more (most of the iconic 80% in fact)!

V0.8

Feature release