views:

44

answers:

2

I would like to specify the structure of underlying child elements based upon an xml attribute value. For example:

<param type="uniform">
    <high>10</high>
    <low>0</low>
</param>

<param2 type="normal">
    <mean>5</mean>
    <stdev>2.5</mean>
<param2>

Is there a way to validate this type of structure using XSD?

+1  A: 

No, unfortunately, this is an area where XSD is lacking - you cannot control the structure based on values in an attribute or element. XSD is strictly about controlling structure.

For something like this, you'd have to use other XML validation techniques, so I suggest you might want to have a look at Schematron:

Schematron is an approach where you can define these kind of dependencies ("if this attribute has value XYZ, then .......").

Marc

marc_s
This is what I suspected was the case. Thanks for validating my thoughts.
Bryan Ward
A: 

You can do something similar using abstract type.

<xs:complexType name="basePqrameterType" abstract="true"/>

Followed by the specific (concrete) type definitions:

<xs:complexType name="Param_uniform">
    <xs:complexContent>
     <xs:extension base="baseParameterType">
      <xs:attribute name="type" use="required" fixed="uniform"/>
      ...<!--other specific restrictions for type uniform-->
     </xs:extension>
     </xs:complexContent>
</xs:complexType>

<xs:complexType name="Param_normal">
    <xs:complexContent>
     <xs:extension base="baseParameterType">
      <xs:attribute name="type" use="required" fixed="normal"/>
      ...<!--other specific restrictions for type normal-->
     </xs:extension>
     </xs:complexContent>
</xs:complexType>

Your xml will look like this:

<Param xsi:type="Param_normal" type="normal"/>
<Param xsi:type="Param_uniform" type="uniform"/>

Thus, it IS possible to have elements with the same name but constrain them due the definition of different types, BUT you cannot 'select' these types by using an attribute value. It has to be doen using the 'xsi:type' notation.

Pieter Degraeuwe