<constraintSpec>

<constraintSpec> (constraint on schema) contains a formal constraint, typically expressed in a rule-based schema language, to which a construct must conform in order to be considered valid [23.5 Element Specifications]
Module tagdocs — Documentation Elements
Attributes
type⚓︎ characterizes the constraintSpec element in some sense; used to indicate when a constraintSpec warns about a deprecated construct.
Status Optional
Datatype teidata.enumerated
Suggested values include:
deprecationWarning
Indicates that this constraint specification warns that some other construct in the schema is deprecated.
scheme⚓︎ supplies the name of the language in which the constraints are defined
Status Optional
Datatype teidata.enumerated
Schematron

<sch:rule context="tei:constraintSpec[ @mode = ('add','replace') or not( @mode ) ]">
<sch:assert test="@scheme">The @scheme attribute of <constraintSpec> is required when the @mode is <sch:value-of select="if (@mode) then concat('"',@mode,'"') else 'not specified'"/>.</sch:assert>
</sch:rule>
Suggested values include:
schematron
(ISO Schematron)
Note

These Guidelines no longer recommend, and the current TEI stylesheets no longer support, the use of Schematron 1.x within constraintSpec. Thus the value schematron is used to indicate that ISO Schematron is used within the constraintSpec.

The scheme attribute is required when the value of mode is add or replace. The scheme attribute is permitted when the value of mode is delete, but these Guidelines make no reccomendation for what a processor should do if its value does not match that of the constraintSpec being deleted.

Member of
Contained by
May contain
Note

A child constraint is required when the mode attribute has the value replace or add (or is not specified, as add is the default). No child elements are permitted when the mode attribute has the value delete. At least one child element is required when the mode attribute has the value change.

Example

This constraint uses Schematron to enforce the presence of the spanTo attribute (which comes from an attribute class) on the addSpan element:

<constraintSpec ident="demo-c1"
 scheme="schematron">

 <desc>Enforce the presence of the <att>spanTo</att> attribute</desc>
 <constraint>
  <sch:rule context="tei:addSpan">
   <sch:assert test="@spanTo">The spanTo= attribute of <sch:name/> is required.</sch:assert>
  </sch:rule>
 </constraint>
</constraintSpec>
Example
<constraintSpec ident="demo-c2"
 scheme="schematron">

 <desc>Implement an accessibility rule which says that pictures
   should have textual explanations</desc>
 <constraint>
  <sch:rule context="tei:figure">
   <sch:report test="not( tei:figDesc | tei:head )">You should
       provide information in a figure from which
       we can construct an alt attribute in HTML</sch:report>
  </sch:rule>
 </constraint>
</constraintSpec>
Example

This constraint uses SPITBOL (a language which is not expressed in XML) to check whether the title and author are identical:

<constraintSpec ident="author_ne_title"
 scheme="SPITBOL">

 <constraint>
   (output = leq(title,author) "title and author cannot be the same")
 </constraint>
</constraintSpec>
Schematron

<sch:rule context="tei:constraintSpec[ @mode eq 'delete']">
<sch:report test="child::*">This constraintSpec element has a mode= of "delete" even though it has child elements. Change the mode= to "add", "change", or "replace", or remove the child elements.</sch:report>
</sch:rule>
<sch:rule context="tei:constraintSpec[ @mode eq 'change']">
<sch:assert test="child::*">This constraintSpec element has a mode= of "change", but does not have any child elements. Specify child elements, or change the mode= to "delete".</sch:assert>
</sch:rule>
<sch:rule context="tei:constraintSpec[ @mode = ('add','replace') ]">
<sch:assert test="child::tei:constraint">This constraintSpec element has a mode= of "<sch:value-of select="@mode"/>", but does not have a child 'constraint' element. Use a child 'constraint' element or change the mode= to "delete" or "change".</sch:assert>
</sch:rule>
Schematron Relationship between scheme attribute and contents: Schematron 1.x

<sch:rule context="tei:constraintSpec">
<sch:report test="tei:constraint/sch1x:* and @scheme = ('isoschematron','schematron')">Rules
in the Schematron 1.* language must be inside a constraintSpec
with a value other than 'schematron' or 'isoschematron' on the
scheme attribute</sch:report>
</sch:rule>
Schematron Relationship between scheme attribute and contents: ISO Schematron

<sch:rule context="tei:constraintSpec[ @mode = ('add','replace') or not( @mode ) ]">
<sch:report test="tei:constraint/sch:* and not( @scheme eq 'schematron')">Rules
in the ISO Schematron language must be inside a constraintSpec
with the value 'schematron' on the scheme attribute</sch:report>
</sch:rule>
Schematron

<sch:rule context="tei:constraintSpec[ @scheme eq 'schematron']/tei:constraint[ .//sch:assert | .//sch:report ]">
<sch:let name="assertsHaveContext"
 value="for $a in .//sch:assert return exists( $a/ancestor::sch:rule/@context )"/>

<sch:let name="reportsHaveContext"
 value="for $r in .//sch:report return exists( $r/ancestor::sch:rule/@context )"/>

<sch:report test="( $assertsHaveContext, $reportsHaveContext ) = false()"
 role="warning">
The use of an <sch:assert> or <sch:report> that does not have a context (i.e., does not have an ancestor <sch:rule> with a @context attribute) in an ISO Schematron constraint specification is deprecated, and will become invalid after 2025-03-15.</sch:report>
</sch:rule>
Schematron

<sch:rule context="tei:constraintSpec[ @mode eq 'add' or not( @mode ) ]">
<sch:let name="myIdent"
 value="normalize-space(@ident)"/>

<sch:report test="preceding::tei:constraintSpec[ normalize-space(@ident) eq $myIdent ]"> The @ident of 'constraintSpec' should be unique; this one (<sch:value-of select="$myIdent"/>) is the same as that of a previous 'constraintSpec'.
</sch:report>
</sch:rule>
Content model
<content>
 <sequence>
  <alternate minOccurs="0"
   maxOccurs="unbounded">

   <classRef key="model.identSynonyms"/>
   <classRef key="model.descLike"/>
  </alternate>
  <elementRef key="constraint"
   minOccurs="0maxOccurs="1"/>

 </sequence>
</content>
Schema Declaration
<rng:element name="constraintSpec">
 <rng:ref name="att.global.attributes"/>
 <rng:ref name="att.global.rendition.attributes"/>
 <rng:ref name="att.global.linking.attributes"/>
 <rng:ref name="att.global.analytic.attributes"/>
 <rng:ref name="att.global.facs.attributes"/>
 <rng:ref name="att.global.change.attributes"/>
 <rng:ref name="att.global.responsibility.attributes"/>
 <rng:ref name="att.global.source.attributes"/>
 <rng:ref name="att.identified.attributes"/>
 <rng:ref name="att.combinable.attributes"/>
 <rng:ref name="att.deprecated.attributes"/>
 <rng:ref name="att.typed.attribute.subtype"/>
 <rng:optional>
  <rng:attribute name="type">
   <rng:choice>
    <rng:value>deprecationWarning</rng:value>
    <rng:ref name="teidata.enumerated"/>
   </rng:choice>
  </rng:attribute>
 </rng:optional>
 <rng:optional>
  <rng:attribute name="scheme">
   <rng:choice>
    <rng:value>schematron</rng:value>
    <rng:ref name="teidata.enumerated"/>
   </rng:choice>
  </rng:attribute>
 </rng:optional>
 <rng:group>
  <rng:zeroOrMore>
   <rng:choice>
    <rng:ref name="model.identSynonyms"/>
    <rng:ref name="model.descLike"/>
   </rng:choice>
  </rng:zeroOrMore>
  <rng:optional>
   <rng:ref name="constraint"/>
  </rng:optional>
 </rng:group>
</rng:element>
element constraintSpec
{
   att.global.attributes,
   att.global.rendition.attributes,
   att.global.linking.attributes,
   att.global.analytic.attributes,
   att.global.facs.attributes,
   att.global.change.attributes,
   att.global.responsibility.attributes,
   att.global.source.attributes,
   att.identified.attributes,
   att.combinable.attributes,
   att.deprecated.attributes,
   att.typed.attribute.subtype,
   attribute type { "deprecationWarning" | teidata.enumerated }?,
   attribute scheme { "schematron" | teidata.enumerated }?,
   ( ( model.identSynonyms | model.descLike )*, constraint? )
}