Home > Tutorial

Define Advanced Constraints

We just went through the definition of every element corresponding to each table in the database. Our modeling task is not ended at this point, as we need to enrich the model with extended functionalities that XML Schema does not natively support.

Extended facets

XML Schema gives the opportunity to specify constraints (a.k.a. facets) on the schema elements. This gives the opportunity to implement business logic across the schema elements and ensure the coherence and integrity of the relationship between elements.

All extended facets are declared under an osd:otherFacets element.

Foreign key constraints

We just learned how to implement the primary keys for all table type elements in our schema. A reference to a table (foreign key) is defined using the extended facet osd:tableRef . This element is defined under the element xs:annotation/xs:appinfo/osd:otherFacets .

As a child of the facet, we may specify:

Example: Ensure that element pub_id in table Titles refers to element pub_id in table Publishers .

<xs:element name="pub_id">
    <xs:annotation>
        <xs:appinfo>
            <
osd:otherFacets>
                <
osd:tableRef>
                    <
tablePath>/root/Publishers</tablePath>
                    <
display>
                       <
pattern xml:lang="en-US">Publisher's name: ${name}</pattern>
                       <
pattern xml:lang="fr-FR">Nom de l'éditeur : ${name}</pattern>
                    </
display>
                </osd:tableRef
>
            </osd:otherFacets
>
        </xs:appinfo
>
    </xs:annotation
>
    <xs:simpleType>
        <xs:restriction base="xs:string">
            <xs:maxLength value="4"/>
        </xs:restriction>
    </xs:simpleType>
</xs:element>

See also:

Dynamic constraints

We can easily specify that the value of element lo_range in table Royalties must be higher than 1:

<xs:element name="lo_rangeminOccurs="0">
    <xs:simpleType>
        <xs:restriction base="xs:int">
            <
xs:minInclusive value="1"/>
        </xs:restriction
>
    </xs:simpleType>
</xs:element>

However, this kind of constraint is static in the declaration, preventing to express constraints between elements.

EBX.Platform provides additional constraints that are not specified in XML Schema, i.e. dynamic constraints. A dynamic constraint is declared on an element, referencing another one, which is semantically linked with it. The two elements are then dynamically compared at runtime, and each time the constraint is breached, an error message is triggered.

Like any other extended facets, the constraint is declared within an xs:annotation/xs:appinfo/osd:otherFacet element.

The osd:otherFacet keeps the same semantic as the xs:restriction element used for static constraints:

Example: Ensure that lo_range value is always lower than hi_range value in the Royalties table.

We implement a dynamic constraint on the lo_range element, referencing the hi_range element.

<xs:element name="lo_rangetype="xs:intminOccurs="0">
    <xs:annotation>
        <
xs:appinfo>
            <
osd:otherFacets>
                <
osd:maxInclusive path="../hi_range"/>
            </osd:otherFacets
>
        </xs:appinfo
>
    </xs:annotation
>
</xs:element>

As displayed in the following EBX.Manager screenshot: when the user submits a lo_range value higher than the hi_range element, a default error message is raised ("the value is too big").

The error message is customizable in the schema under the osd:otherFacets element, using the osd:defaultErrorMessage element.

<xs:element name="lo_rangetype="xs:intminOccurs="0">
    <xs:annotation>
        <xs:appinfo>
            <osd:otherFacets>
                <osd:maxInclusive path="../hi_range">
                    <osd:defaultErrorMessage xml:lang="en-US">
low range value must be lower than higher range value
                    </osd:defaultErrorMessage>
                    <
osd:defaultErrorMessage xml:lang="fr-FR">
la valeur de la borne inférieure doit être inférieure à la valeur de la borne supérieure
                    </osd:defaultErrorMessage
>
                </osd:maxInclusive>
            </osd:otherFacets>
        </xs:appinfo>
    </xs:annotation>
</xs:element>

The message can be localized and customized for the user need.

See also:

excludeValue Constraint

EBX.Platform also provides extended facets aimed at preventing a specific value for an element.

The osd:excludeValue element is dedicated for that purpose. It accepts a value as an attribute, which specifies the reject value for the element.

Example: Ensure that lo_range value is different from value "1" in the Royalties table .

<xs:element name="lo_rangetype="xs:intminOccurs="0">
    <xs:annotation>
        <xs:appinfo>
            <osd:otherFacets>
                <osd:excludeValue value="1">
                    <osd:defaultErrorMessage xml:lang="en-US">
low range value must be different than value 1</osd:defaultErrorMessage>
                    <osd:defaultErrorMessage xml:lang="fr-FR">
la valeur de la borne inférieure doit être différente de 1</osd:defaultErrorMessage>
                </osd:excludeValue>
            </osd:otherFacets>
        </xs:appinfo>
    </xs:annotation>
</xs:element>

See also:

excludeSegment Constraint

Following the same principle as the excludeValue constraint, the excludeSegment element prevents the element value from being out of the specified range.

Please note that the boundaries of the range are excluded.

Example: Ensure that lo_range value is out of range (100,200) in the Royalties table.

<xs:element name="lo_rangetype="xs:intminOccurs="0">
    <xs:annotation>
        <xs:appinfo>
            <osd:otherFacets>
                <osd:excludeSegment minValue="100maxValue="200">
                    <osd:defaultErrorMessage xml:lang="en-US">
low range value must be out of range [100,200]</osd:defaultErrorMessage>
                    <osd:defaultErrorMessage xml:lang="fr-FR">
la valeur de la borne inférieure doit être hors de la plage [100,200]</osd:defaultErrorMessage>
                </osd:excludeSegment>
            </osd:otherFacets>
        </xs:appinfo>
    </xs:annotation>
</xs:element>

See also:

Resource constraint

It may sometimes be useful to declare an external resource in the model. For instance, an image or HTML resource can enhance the look and feel of an instance screen in EBX.Manager.

In our sample database context, we could add a field called front_picture in table titles that refers to an image, i.e. the front page of the book.

This can be done easily, using the osd:FacetOResource .

<xs:element name="front_picturetype="osd:resourceminOccurs="0">
    <xs:annotation>
        <xs:appinfo>
            <osd:otherFacets>
                <
osd:FacetOResource 
                    osd:moduleName="wbp
                    osd:resourceType="ext-images
                    osd:relativePath="frontpages/"/>

            </osd:otherFacets
>
        </xs:appinfo>                    
    </xs:annotation>
</xs:element>

Please note about the osd:FacetOResource attributes:

See also:

Next: Develop Programmatic Constraints >

Home > Tutorial