I explored this in a number of different ways to see how constraints could be modeled. What I wound up doing was breaking a conformance statement down into three separate parts:
- The basic conformance statement, mostly embodying the conformance level.
- Constraints that can be applied to it, cardinality, existence, and all match.
- Match patterns that can be used with it.
1. Conformance Statement
The basic object is a conformance statement. Each conformance statement has a conformance level:
- SHOULD NOT
- SHALL NOT
This corresponds to the error level reported by a conformance test, and follows the usual meanings in RFC-2119.
2.1 Cardinality Constraint
There conformanceLevel exist some number of X items
The basic constraint is on the cardinality of the item, and is expressed in a min/max form, where 0 <= min <= max <= ∞ and min < ∞.
2.2 Existence Constraint
There conformanceLevel exists some number of X items that match pattern P.
This is the existence constraint that I talked about yesterday.
2.3 All Match Constraint
There conformanceLevel are some number of X items and all match pattern P.
This could also be expressed as two existence constraints:
There conformanceLevel exist some number of X items that match pattern P
There conformanceLevel exist 0 X items that match pattern !P
Patterns are used to express different constraints and test conditions.
3.1. Range Pattern
A range pattern is an abstract pattern that places a limit on particular values that a data element can have.
3.1.1 Value Pattern
X.V = Y
The value pattern is an abstract extension of the Range Pattern, restricting a data element to contain a single value.
22.214.171.124 Specific Identifier Pattern
X.root = Y.root
X.extension = Y.extension
This is an extension to the Value Pattern where the data element being constrained is of the II data type. It is commonly used to require a class to assert conformance to a specific template, and in the typeId constraint found in CDA.
126.96.36.199 Specific Code Pattern
X.code = Y.code
X.codeSystem = Y.codeSystem
Similar to the Specific Identifier pattern, this requires the use of a specific code instead of an identifier. It can be applied to any data element of the CD or derived data types. It is commonly used in CDA fixed attributes (classCode and moodCode), and in section templates.
3.1.2 Identifier Namespace Pattern
X.root = Y.root
This is also an extension to the range pattern where the data element being constrained by come from a specific namespace or assigning authority. It can be used to require provider identifiers from a given assigning authority (e.g., NPI or DEA).
188.8.131.52 Vocabulary/Value Set Pattern
X.V is an element of Y
This is an extension of the Range pattern used to require use of a specific vocabulary or value set. This is also applied to data elements of the CD or derived data types. It is commonly used to restrict the value of the code element in CDA documents, but can also be applied to the value element.
184.108.40.206 Data Type Pattern
X is of Type Y
This extends the range pattern and fixes the data type or data type flavor (a restriction on a data type) of an element to one of a specific list of possible types. It is used most commonly on elements using the GTS data type, but can also be applied to other elements (e.g., the value element in CDA which is of unspecified type). Restrictions on name and addr elements are data type patterns (not templates), as they specify a data type flavor to be applied to the name and addr elements.
220.127.116.11 Contains Text Pattern
X.text contains "Allergies"
This extends the range patter and requires the content of a text element to contain a specific value. This type of constraint was used in CCD to restrict the titles in sections.
3.2 Contains Template Pattern
X.association.templateId = Y
This template is used to specify the inclusion of an association (participant, act relationship, role or entity) in a higher level class that conforms to a given template.
3.3 Logical Operator Pattern
Patterns can be combined using logical operators (AND/OR/XOR). This pattern allows any number of other patterns (including the Logical Operator Pattern) to be combined using the AND, OR and XOR. When combined with AND, all patterns must match, with OR, at least one must match, and with XOR, only one of the patterns is allowed to match.