tags:

views:

506

answers:

3

I have a problem making an xsd file. I need to have an xsd file for xml documents which will look like this:

<message type="login">
  <login nick="Ben" gameId="chess" desiredRole="simple "/>
</message>

or like this

<message type="error">
  Error message
</message>

Meaning there is always a message tag but it has different attribute type values and depending on type value there are different things inside the message tag. I tried something like this:

<xsd:element name ='message' type='messageType'>
</xsd:element>

<xsd:complexType name='messageType'/>
  <xsd:complexType name='error'>
    <xsd:complexContent>
      <xsd:extension base='messageType'>
        <xsd:attribute name ='type' use='required'>
          <xsd:simpleType>
            <xsd:restriction base='xsd:string'>
              <xsd:enumeration value='error'/>
            </xsd:restriction>
          </xsd:simpleType>
        </xsd:attribute>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>

  <xsd:complexType name='login'>
    <xsd:complexContent>
      <xsd:extension base='messageType'>
        <xsd:sequence>
          <xsd:element name='login'>
            <xsd:complexType>
              <xsd:attribute name='nick' type='xsd:string' use='required'>
              </xsd:attribute>
              <xsd:attribute name='gameId' type='xsd:string' use='required'>
              </xsd:attribute>
              <xsd:attribute name='desiredRole' type='xsd:string' use='required'>
              </xsd:attribute>
            </xsd:complexType>
          </xsd:element>
        </xsd:sequence>
        <xsd:attribute name ='type' use='required'>
          <xsd:simpleType>
            <xsd:restriction base='xsd:string'>
              <xsd:enumeration value='login'/>
            </xsd:restriction>
          </xsd:simpleType>
        </xsd:attribute>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>

</xsd:schema>

but it doesn’t work (I get an error that the attribute type was not defined). Can some one please help me with this?

A: 

How about

<message>
    <login />
</message>

and

<message>
    <error />
</message>

That is, leave off the type attribute, and always have an element inside of message.

John Saunders
A: 

Can't do that. Types of xml files are define for me - I can't change them.

+1  A: 

XSD doesn't allow you to do precisely what you want to do, which is create an element that has different structures depending on attribute values. However, if you truly need this element to have different structures like this, you can create an element definition that allows all possible structures. You just cannot have it automatically validated by the parser to prove that it conforms to either one definition or the other, exclusively. Not within XSD at any rate.

Try something like this:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
  <xsd:element name="message" type="messageType"/>

  <xsd:simpleType name="typeType">
    <xsd:restriction base="xsd:string">
      <xsd:enumeration value="login"/>
      <xsd:enumeration value="error"/>
    </xsd:restriction>
  </xsd:simpleType>

  <xsd:element name="login">
    <xsd:complexType>
      <xsd:attribute name='nick'        type='xsd:string' use='required'/>
      <xsd:attribute name='gameId'      type='xsd:string' use='required'/>
      <xsd:attribute name='desiredRole' type='xsd:string' use='required'/>
    </xsd:complexType>
  </xsd:element>

  <xsd:complexType name='messageType'/>
    <xsd:sequence>
      <xsd:element ref="login" minOccurs="0" maxOccurs="1"/>
    </xsd:sequence>
    <xsd:attribute name="type" type="typeType" use="required"/>
  </xsd:complexType>
</xsd:schema>
Eddie