Reputation: 9
The element title has an optional attribute languageCode. How can I do the following? If the attribute is used, an element with languageCode 'en' is required. For example...
The following is wrong because there is no element with the en languagecode:
<tns:Lessons>
<tns:Title language="fr">TitleFR</tns:Title>
<tns:Title language="de">TitleDE</tns:Title>
</tns:Lessons>
The following is correct because the languageCode is optional:
<tns:Lessons>
<tns:Title>Title1</tns:Title>
</tns:Lessons>
The following is correct because the languageCode en exists:
<tns:Lessons>
<tns:Title language="en">TitleEN</tns:Title>
<tns:Title language="de">TitleDE</tns:Title>
</tns:Lessons>
What I have managed so far is this xsd.
<xsd:element name="Lessons">
<xsd:complexType>
<xsd:sequence>
<xsd:element minOccurs="1" maxOccurs="unbounded" ref="tns:Title" />
</xsd:sequence>
</xsd:complexType>
<xsd:unique name="UniqueTitle">
<xsd:selector xpath="tns:Title"/>
<xsd:field xpath="@language"/>
</xsd:unique>
</xsd:element>
<xsd:complexType name="i18nNonEmptyString">
<xsd:simpleContent>
<xsd:extension base="tns:NonEmptyString">
<xsd:attribute name="language" type="tns:LanguageCode" use="required" default="en" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:element name="Title" type="tns:i18nNonEmptyString"/>
<xsd:simpleType name="LanguageCode">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="en"/>
<xsd:enumeration value="de"/>
<xsd:enumeration value="fr"/>
</xsd:restriction>
</xsd:simpleType>
Upvotes: 1
Views: 1040
Reputation: 3464
If you can use XML Schema 1.1 then it should be as simple as adding <xsd:assert test="fn:count(./Title[@language='en']) eq 1"/>
to the Lessons element. For details see http://www.w3.org/TR/xmlschema11-1/#cAssertions. For an intro and some examples see https://blogs.oracle.com/rammenon/entry/xml_schema_11_what_you_need_to.
If you are stuck with XML Schema 1.0 then (I think) it can not be done unless you introduce differently named elements for en and non-en Titles. (Because the model of Lessons must be unambiguous "Title" can not refer to both en-restricted and non-restricted type of Title.) See Validating the child's age against the parents age in xsd for a similar discussion.
Traditionally, Schematron has been used with XML Schema 1.0 to model assertions that go beyond XML Schema 1.0. See Wikipedia. In its simplest form Schematron is implemented as XSLT stylesheet which produces a stylesheet from a spec which checks XML documents against that spec. For a compact intro see http://www.ldodds.com/papers/schematron_xsltuk.html#c35e2592b5b4. For a link collection see Resource Directory (RDDL) for Schematron 1.5.
If you have only very few checks to do and choose to use XSLT for the checks, then you may want to write the XSLT by hand to avoid having to learn Schematron.
Upvotes: 1