2

I want to validate a XML file and to make sure it has a root element called speak like this:

<speak>
  <!--other node here...-->
</speak>

the speak element must exist in XML and must appears only once. I try to add code below in my XSD file:

<xsd:element name="speak" type="speak" minOccurs="1" maxOccurs="1"/>

But it does not work.

kjhughes
  • 106,133
  • 27
  • 181
  • 240
Jiewen Zheng
  • 93
  • 1
  • 4

3 Answers3

1

In the schema itself, you can't put a constraint on what the root element must be. (That's by design, though not everyone thinks it's a good design.) Any global element declaration can match the root element.

Some APIs for invoking validation may allow you to constrain the root element. For example, if you use the Saxon schema validator and run it from the command line, you can specify -top:speak to require that the top-level element is named speak.

Michael Kay
  • 156,231
  • 11
  • 92
  • 164
  • 2
    I think you may be answering a more general question than OP is asking. With full control over the XSD design, one can define only a single element globally. Then, only XML documents with that root element will validate with the XSD. Without control over the XSD, if multiple global element definitions exist, then you're right that one cannot select which must be the root element of any given XML document, [as you've noted in the past](https://stackoverflow.com/a/8857777/290085). – kjhughes Mar 06 '19 at 13:19
  • 2
    Writing a schema with only a single global element declaration isn't really feasible for anything but the most trivial of document models. – Michael Kay Mar 06 '19 at 14:54
  • Complex document model authors wouldn't typically be asking about occurrence constraints on global element declarations. ;-) Besides, one can do a lot with a single global element declaration with the [Russian Doll or Venetian Blind patterns](http://www.xfront.com/GlobalVersusLocal.html). – kjhughes Mar 09 '19 at 19:22
0

XSD occurrence constraints are not allowed on root elements because XML documents are already constrained to consist of a single root element. Therefore, simply specify a single global element declaration, and make declaration be for the required root element in your XML. It will effectively be minOccurs="1" maxOccurs="1" anyway then.

kjhughes
  • 106,133
  • 27
  • 181
  • 240
0

You can use minOccurs/maxOccurs on the sequence element, like the following:

 <xs:element name="speak">
     <xs:complexType>
         <xs:sequence minOccurs="1" maxOccurs="1">
             ...
         </xs:sequence>
     </xs:complexType>
 </xs:element>

but it is not necessary, as it is a redundant default attribute value assignment.

hce
  • 1,107
  • 9
  • 25
  • This is not the right way. what i want is making "speak" appear only once. not the sub-node of "speak". – Jiewen Zheng Mar 07 '19 at 02:41
  • Oh sorry, Well this is not possible. As stated by others, you dont need to, as xml is hierarchical and as long as speak is not nested in another sequence, it is not necessary to define a constraint. – hce Mar 07 '19 at 08:30