0
votes

I am facing the following problem. I need to create an XSD schema of my XML file. Let's say that I have several "Conversation Objects" nodes:

  • Message
  • End
  • YesOrNoAnswer

which are simple elements (or almost) that I am able to describe in my XSD. For example my End node is defined in this way:

<xs:element name="END" type="EndType"/>

<xs:complexType name="EndType" />
    <xs:attribute name="completedMission" type="xs:string"/>
    <xs:attribute name="retry" type="xs:boolean"/>
</xs:complexType>

Then I have a special one called:

  • multipleChoice

This kind of element has the following structure:

<multipleChoice actor="" numberOfChoices="" percentage=""> message text

    <choice>
        <effects name="" bar="" points="" action="" likelihood="" />
        ...
    </choice>

    <choice>
       <effects name="" bar="" points="" action="" likelihood="" />
       ...
    </choice>

    <choice>
       <effects name="" bar="" points="" action="" likelihood="" />
       ...
    </choice>

</multipleChoice>

So, the first problem is:

  • there have to be the same number of "choice" nodes as defined in the "numberOfChoices" attribute
  • the "choice" node has to be followed by the "effect" node, which is just containing some attributes
  • after the "effect" node any other kind of node can be inserted, without any order and as many times as we want. For example any of the simple ones (Message, End, YesOrNoAnswer) or "multipleChoice" nodes, allowing nesting in as many level of depth as we want.

How can I define the "multipleChoice" node in XSD (including attributes, text, "choice" and "effect" nodes) ? Thanks in advance!

1
Can you use XSD 1.1? You will need it to check, at least, your constraint involving numberOfChoices. Before anyone spends any time on the rest of your problem, let us know if you can use XSD 1.1; for example, Microsoft has only implemented XSD 1.0. - kjhughes
@kjhughes I have no specific requirement for using XSD 1.0 or 1.1 . The only thing is that I can easily find a validator for XSD 1.0 while for XSD 1.1 it seems more complicated and I have lack of time. Therefore, if the solution that you propose is much more elegant and reliable with XSD 1.1, I'll spend more time looking for a proper validator. Otherwise, if the same solution can be expressed in XSD 1.0 without any problem, I would prefer to use this last one. - Tarta
@kjhughes just found a working validator for XSD 1.1 . So, 1.1 will be fine. - Tarta

1 Answers

1
votes

How about this answer -it works only in XSD 1.1! Updated based on feedback from @Tarta.

  <xs:element name="multipleChoice">
    <xs:complexType>
      <xs:sequence>
        <xs:element minOccurs="0" maxOccurs="unbounded" ref="choice"/>
      </xs:sequence>
      <xs:attribute name="actor"/>
      <xs:attribute name="numberOfChoices"/>
      <xs:attribute name="percentage"/>
      <xs:assert test="count(./choice) = @numberOfChoices"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="choice">
    <xs:complexType>
      <xs:sequence>
        <xs:element minOccurs="1" maxOccurs="1" ref="effects"/>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:element minOccurs="0" maxOccurs="unbounded" ref="Message"/>
          <xs:element minOccurs="0" maxOccurs="unbounded" ref="End"/>
          <xs:element minOccurs="0" maxOccurs="unbounded" ref="YesOrNoAnswer"/>
          <xs:element minOccurs="0" maxOccurs="unbounded" ref="multipleChoice"/>          
        </xs:choice>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="effects">
    <xs:complexType>
      <xs:attribute name="name"/>
      <xs:attribute name="bar"/>
      <xs:attribute name="points"/>
      <xs:attribute name="action"/>
      <xs:attribute name="likelihood"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="Message">
    <xs:simpleType>
      <xs:restriction base="xs:string"/>
    </xs:simpleType>
  </xs:element>
  <xs:element name="End">
    <xs:simpleType>
      <xs:restriction base="xs:string"/>
    </xs:simpleType>
  </xs:element>
  <xs:element name="YesOrNoAnswer">
    <xs:simpleType>
      <xs:restriction base="xs:string"/>
    </xs:simpleType>
  </xs:element>

That should give the correct number of choice elements for each multipleChoice, using the assert to enforce that. It also allows the nesting of elements.

This version now starting with exactly 1 effects element and then 0 or more of the other elements in any order.