Reputation: 1
Is it possible to define an xsd scheme which could validate such xml:
<test>
<name Type="1" SomeAttr="value" >
<info a="1" b="2"/>
</name>
<name Type="3" SomeAttr="value" />
</test>
In this xml can be 1 or 2 elements "name".
In first element "name" in attribute "Type" can be only 2 values - 1 or 2
In second element "name" in attribute "Type" can be only 1 value - 3
In xml can be only 1 child element "info" and it must treated to parent element "name" with attributes value 1 or 2 (not to "name" with Type="3")
Please help. Thank you.
Upvotes: 0
Views: 394
Reputation: 3290
In Xml Schema 1.1 it is possible using the xs:alternative
that allows an element to have different types based on provided condition.
<xs:element name="name">
<xs:alternative test="@Type=1" type="name_type_1"/>
<xs:alternative test="@Type=3" type="name_type_3"/>
</xs:element>
The full schema for the XML in the question could look like:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
elementFormDefault="qualified"
attributeFormDefault="unqualified"
vc:minVersion="1.1">
<xs:element name="test">
<xs:complexType>
<xs:sequence>
<xs:element name="name" minOccurs="0" maxOccurs="unbounded">
<xs:alternative test="@Type=1" type="name_type_1"/>
<xs:alternative test="@Type=3" type="name_type_3"/>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="name_type_1">
<xs:sequence>
<xs:element name="info">
<xs:complexType>
<xs:attribute name="a"/>
<xs:attribute name="b"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="Type" type="xs:integer"/>
<xs:attribute name="SomeAttr"/>
</xs:complexType>
<xs:complexType name="name_type_3">
<xs:attribute name="Type" type="xs:integer"/>
<xs:attribute name="SomeAttr"/>
</xs:complexType>
</xs:schema>
Upvotes: 0
Reputation: 25054
In XSD, any two elements of the same name appearing as children of the same parent must have the same type. (I am omitting some complications here; readers who need full information will have to consult the spec.) It is a consequence of this that in a typical document validation the type associated with an element is fully determined by the path from the root of the validation episode to the element itself, and does not depend upon its position among the children of its parent.
So: no, you cannot give two sibling elements the same name and different types.
If the two elements occur in different contexts, they can have different types. So XML like the following would work:
<test>
<context-1>
<name Type="1" SomeAttr="value" >
<info a="1" b="2"/>
</name>
</context-1>
<context-2>
<name Type="3" SomeAttr="value" />
</context-2>
</test>
But the simplest way to have your two 'name' elements have different types is to give them different names, reflecting the difference in their natures.
<test>
<red-name Type="1" SomeAttr="value" >
<info a="1" b="2"/>
</red-name>
<green-name Type="3" SomeAttr="value" />
</test>
If you want the schema to reflect, somehow, that the two forms of name are somehow different forms of the same thing, XSD provides two obvious mechanisms:
You can define a name
type, from which the red and green flavors of the type are derived. The relation between the two types is thus reflected in the type hierarchy.
You can define an abstract (or a concrete!) name
element and declare the two specific variants (here called red-name
and green-name
) as being substitutable for it. The relation between the red and green name elements is thus reflected in the substitution-group relations.
Upvotes: 1