Is it possible to define in XML Schema an condition based on attribute value? For example, when test@attrib="one"
, I want one-element
to be allowed and mandatory or when test@attrib="two"
, I want two-element
to be allowed and mandatory.
For example, valid documents are:
<root>
<test attrib="one"/>
<some-element-1/>
<some-element-2/>
...
<some-element-n/>
<one-element>
</one-element>
</root>
or
<root>
<test attrib="two"/>
<some-element-1/>
<some-element-2/>
...
<some-element-n/>
<two-element>
</two-element>
</root>
Wrong documents:
<root>
<test attrib="one"/>
<some-element-1/>
<some-element-2/>
...
<some-element-n/>
</root>
or
<root>
<test attrib="two"/>
<some-element-1/>
<some-element-2/>
...
<some-element-n/>
<one-element>
</one-element>
</root>
Is it possible in XSD?
Attributes are either optional or mandatory (by default they are optional). The "use" property in the XSD definition is used to specify if the attribute is optional or mandatory. To specify that an attribute must be present, use="required" (Note: use may also be set to "prohibited", but we'll come to that later).
An attribute provides extra information within an element. Attributes are defined within an XSD as follows, having name and type properties. An Attribute can appear 0 or 1 times within a given element in the XML document. Attributes are either optional or mandatory (by default the are optional).
The 'noNamespaceSchemaLocation' attribute is used to reference XML Schema(s) that are not defined in a target-namespace.
Not within the same type. You would need to define a different type for each of the different options.
UPDATE
To re-use type definitions in your schema:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://My.Schema.Namespace"
targetNamespace="http://My.Schema.Namespace">
<xs:element name="root">
<xs:complexType>
<xs:choice>
<xs:element name="test1" type="test1Type" />
<xs:element name="test2" type="test2Type" />
</xs:choice>
</xs:complexType>
</xs:element>
<!-- define the two root types -->
<xs:complexType name="test1Type">
<xs:all>
<xs:element name="some-element-1" type="some-element-1Type" />
<xs:element name="some-element-2" type="some-element-2Type" />
<xs:element name="some-element-3" type="some-element-3Type" />
<xs:element name="one-element" type="one-elementType" />
</xs:all>
<xs:attribute name="attrib" type="xs:string" fixed="one" />
</xs:complexType>
<xs:complexType name="test2Type">
<xs:all>
<xs:element name="some-element-1" type="some-element-1Type" />
<xs:element name="some-element-2" type="some-element-2Type" />
<xs:element name="some-element-3" type="some-element-3Type" />
<xs:element name="two-element" type="two-elementType" />
</xs:all>
<xs:attribute name="attrib" type="xs:string" fixed="two" />
</xs:complexType>
<!-- Define re-usable types-->
<xs:complexType mixed="true" name="some-element-1Type"/>
<xs:complexType mixed="true" name="some-element-2Type"/>
<xs:complexType mixed="true" name="some-element-3Type"/>
<xs:complexType mixed="true" name="one-elementType"/>
<xs:complexType mixed="true" name="two-elementType"/>
</xs:schema>
This will validate:
<?xml version="1.0" encoding="utf-8" ?>
<root xmlns="http://My.Schema.Namespace">
<test1 attrib="one">
<some-element-1>sadas</some-element-1>
<some-element-2>sadas</some-element-2>
<some-element-3>sadas</some-element-3>
<one-element>sadas</one-element>
</test1>
</root>
and
<?xml version="1.0" encoding="utf-8" ?>
<root xmlns="http://My.Schema.Namespace">
<test2 attrib="two">
<some-element-1>sadas</some-element-1>
<some-element-2>sadas</some-element-2>
<some-element-3>sadas</some-element-3>
<two-element>sadas</two-element>
</test2>
</root>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With