Leroy Jenkins Coder
Leroy Jenkins Coder

Reputation: 71

Can an XSD specify a list of an element OR a single element as the root?

Is is possible to create an XSD which will validate both this:

<ImageS xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://example.com/schemas/myschema.xsd">
  <Image>
      <Url>http://www.nowhere.com/nothing.gif</Url>
  </Image>
  <Image>
      <Url>http://www.somewhere.com/somewhere.gif</Url>
  </Image>
</ImageS>

And this:

<Image xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://example.com/schemas/myschema.xsd">
    <Url>http://www.yetanotheraddress.com/something.gif</Url>
</Image>

I've been trying to do this using a choice element:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="myImages" 
    targetNamespace="http://example.com/schemas/myschema.xsd"
    elementFormDefault="qualified"
    xmlns="http://example.com/schemas/myschema.xsd"
    xmlns:mstns="http://example.com/schemas/myschema.xsd"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:choice minOccurs="0">
        <xs:element name="ImageS" type="xs:ImageList" />
        <xs:element name="Image" type="xs:Image" />
    </xs:choice>

    <xs:complexType name="ImageList">
        <xs:sequence>
            <xs:element name="Image" type="Image" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="Image">
        <xs:sequence>
        <xs:element name="Url" type="someString"/>
        </xs:sequence>
    </xs:complexType>
    <xs:simpleType name="someString">
        <xs:restriction base="xs:string">
            <xs:minLength value="0"/>
            <xs:maxLength value="50"/>
        </xs:restriction>
    </xs:simpleType>
</xs:schema>

It doesn't seem to work when I try to use it. I keep getting this error when trying to add the xsd to a C# XmlSchemaSet:

XmlSchemaException: The 'http://www.w3.org/2001/XMLSchema:choice' element is not supported in this context.

This leads me to believe that what I'm doing can't be done in that manner.

Can an XSD be created that defines items in a list or just an individual item?

Upvotes: 0

Views: 632

Answers (2)

Michael Kay
Michael Kay

Reputation: 163635

A schema doesn't define a root element for the document. Every global element declaration defines a potential validation root. To put it another way, a schema defines valid elements, not valid documents. So you don't need to say that the root can be either an Image or an ImageS, that's true without you needing to say anything.

Upvotes: 0

Mitch
Mitch

Reputation: 22311

Validation starts based off of the root element. You can have multiple roots per schema, just remove the <xsd:choice element.

Corrected XSD:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="myImages" 
    targetNamespace="http://example.com/schemas/myschema.xsd"
    elementFormDefault="qualified"
    xmlns="http://example.com/schemas/myschema.xsd"
    xmlns:mstns="http://example.com/schemas/myschema.xsd"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:element name="ImageS" type="ImageList" />
    <xs:element name="Image" type="Image" />

    <xs:complexType name="ImageList">
        <xs:sequence>
            <xs:element name="Image" type="Image" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="Image">
        <xs:sequence>
        <xs:element name="Url" type="someString"/>
        </xs:sequence>
    </xs:complexType>
    <xs:simpleType name="someString">
        <xs:restriction base="xs:string">
            <xs:minLength value="0"/>
            <xs:maxLength value="50"/>
        </xs:restriction>
    </xs:simpleType>
</xs:schema>

You also had an error in that the type specified for the ImageS and Image elements was xs:ImageList and xs:Image respectively. That would imply that those types live in http://www.w3.org/2001/XMLSchema rather than your schema. Remove the xs: to fix.

Upvotes: 2

Related Questions