12

I would like to create XML Schema for this chunk of xml, I would like to restrict the values of "name" attribute, so that in output document on and only one instance of day is allowed for each week day:

<a>
  <day name="monday" />
  <day name="tuesday" />
  <day name="wednesday" />
</a>

I have tried to use this:

 <xs:complexType name="a">
  <xs:sequence>
    <xs:element name="day" minOccurs="1" maxOccurs="1">
      <xs:complexType>
        <xs:attribute name="name" use="required">
          <xs:simpleType>
            <xs:restriction base="xs:string">
              <xs:enumeration value="monday" />
            </xs:restriction>
          </xs:simpleType>
        </xs:attribute>
      </xs:complexType>
    </xs:element>
    <xs:element name="day" minOccurs="1" maxOccurs="1">
      <xs:complexType>
        <xs:attribute name="name" use="required">
          <xs:simpleType>
            <xs:restriction base="xs:string">
              <xs:enumeration value="tuesday" />
            </xs:restriction>
          </xs:simpleType>
        </xs:attribute>
      </xs:complexType>
    </xs:element>
  </xs:sequence>
</xs:complexType>

but XML Schema validator in eclipse says error "Multiple elements with name 'day', with different types, appear in the model group.".

Is there any other way?

5 Answers 5

15

You need something like this:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
  <xs:element name="a">
    <xs:complexType>
      <xs:sequence>
        <xs:element maxOccurs="unbounded" ref="day"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="day">
    <xs:complexType>
      <xs:attribute name="name" use="required">
        <xs:simpleType>
            <xs:restriction base="xs:string">
                <xs:enumeration value="monday"/>
                <xs:enumeration value="tuesday"/>
                <xs:enumeration value="wednesday"/>
            </xs:restriction>
        </xs:simpleType>
        </xs:attribute>
    </xs:complexType>
  </xs:element>
</xs:schema>
Sign up to request clarification or add additional context in comments.

1 Comment

No, this does not do the trick. If the goal is to allow one-and-only-one element for each day name, this schema won't do it. You need to use xs:unique to formally stipulate the each-day-at-most-once constraint.
10

In order to satisfy the at-most-once constraint described in the original question, you need to use a xs:unique element in your schema.

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified">

  <xs:element name="a">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="day" maxOccurs="7" minOccurs="1">
          <xs:complexType>
            <xs:attribute name="name" use="required">
              <xs:simpleType>
                <xs:restriction base="xs:string">
                  <xs:pattern value="(mon|tues|wednes|thurs|fri|satur|sun)day"/>
                </xs:restriction>
              </xs:simpleType>
            </xs:attribute>
          </xs:complexType>
          <xs:unique name="eachDayAtMostOnce">
            <xs:selector xpath="day"/>
            <xs:field xpath="@name"/>
          </xs:unique>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

</xs:schema>

Comments

1

Have you considered something like this? (i.e. day is a type, and the elements are named after the days of the week)

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:complexType name="day" />
  <xs:element name="a">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="monday" maxOccurs="1" minOccurs="0" type="day" />
        <xs:element name="tuesday" maxOccurs="1" minOccurs="0" type="day" />
        <xs:element name="wednesday" maxOccurs="1" minOccurs="0" type="day" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

1 Comment

Yes I did, actually I use exactly this right now, but the questioned xml desing seemed to me as more appropriate. Thanks anyway.
0

Try this:

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="a">
    <xs:complexType>
        <xs:sequence>
            <xs:element maxOccurs="unbounded" name="day">
                <xs:complexType>
                    <xs:attribute name="atrib" type="xs:string" use="required" />
                </xs:complexType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>
</xs:element>

I think the maxOccurs="unbounded" is what you need.

1 Comment

I wanted to restrict also values of attribute, I have clarified the question accordingly.
0

Use choice instead of sequence

By that way u can have only day element one's in a element

And for name attribute use ref attribute and reference it with enumeration

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.