minOccurs and maxOccurs on elements inside xsd:choice

时光怂恿深爱的人放手 提交于 2020-01-04 21:44:29

问题


I have a root element <a> and its children <b>, <c>, <d>

Here's what I need:

  • the child elements can appear in any order
  • just 1 <b>
  • more than 1 <c>
  • 0 or 1 <d>

For example:

<a>
    <c />
    <b />
    <c />
    <d /> 
</a>

And here is my XSD:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified">
  <xs:element name="a">
    <xs:complexType>
      <xs:choice>
        <xs:element name="b" />
        <xs:element name="c" minOccurs="1" maxOccurs="unbounded"/>
        <xs:element name="d" minOccurs="0" maxOccurs="1"/>
      </xs:choice>
    </xs:complexType>
  </xs:element>
</xs:schema>

But the minOccurs and maxOccurs in xs:element may not work. When I run the example, I got an error:

Element <b> is not allowed at this location under element <a>.

How can I fix this?


回答1:


Here's what your XSD says: Within a you can choose one of the following options:

  1. A single b element.
  2. One or more c elements.
  3. Zero or one d elements.

Your XML chooses option #2. It doesn't get a second choice, and when the parser encounters the b element, it correctly reports the violation.

You might think you could fix this by granting multiple choices:

  <xs:choice maxOccurs="unbounded">

This would now say: Within a you can repeatedly choose one of the following options:

  1. A single b element.
  2. One or more c elements.
  3. Zero or one d elements.

Your XML would now choose option #2, then option #1, then option #2, then option #3, then declare that your XML is valid. Success?

No, not if, for example, you wish to ensure only one b element child because the choice itself is repeated, and option #1 can be repeatedly selected, each time allowing a single b element, but in aggregate, effectively allowing multiple b elements.

For this reason, xsd:choice and, in fact, XSD 1.0 in general cannot be used to represent your constraint.

Your options? Check this constraint in code outside of XSD, or use XSD 1.1's xsd:assert:

XSD 1.1 Solution

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
           vc:minVersion="1.1">
  <xs:element name="a">
    <xs:complexType>
      <xs:choice maxOccurs="unbounded">
        <xs:element name="b" />
        <xs:element name="c"/>
        <xs:element name="d"/>
      </xs:choice>
      <xs:assert test="count(b) = 1 and count(c) > 1 and count(d) >= 0"/>
    </xs:complexType>
  </xs:element>
</xs:schema>


来源:https://stackoverflow.com/questions/28112263/minoccurs-and-maxoccurs-on-elements-inside-xsdchoice

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!