XMLSpy忽略“minOccurs”?为什么这个XML有效?

时间:2010-09-08 13:56:31

标签: xml xsd xmlspy

请告诉我为什么 XML Spy 认为这是有效。仅供参考,这指定了SQL查询。这里是 XML

 <sideBar title="LabelSearch">
  <searchLabel table="ID=*.companies">
   <filter accessRight="r">
    <and>
     <filterElement argument="companies.Type" operator="=" value="Client"/>
    </and>
   </filter>
  </searchLabel>
 </sideBar>

问题:我不应该只允许在“and”标记内放入一个filterElement,但至少有两个。如果我只有一个filterElement,我应该使用它而不包含周围的“and”标记。这里是 XSD

 <xs:complexType name="filterGroupType">
  <xs:sequence>
   <xs:choice>
    <xs:element name="or" type="filterGroupOrType"/>
    <xs:element name="and" type="filterGroupAndType"/>
    <xs:element name="filterElement" type="filterType"/>
   </xs:choice>
  </xs:sequence>
  <xs:attribute name="accessRight" type="accessRightSimpleType" use="required"/>
 </xs:complexType>
 <xs:complexType name="filterGroupAndType">
  <xs:sequence minOccurs="2" maxOccurs="unbounded">
   <xs:element name="or" type="filterGroupOrType" minOccurs="0"/>
   <xs:element name="filterElement" type="filterType" minOccurs="0"/>
  </xs:sequence>
 </xs:complexType>
 <xs:complexType name="filterGroupOrType">
  <xs:sequence minOccurs="2" maxOccurs="unbounded">
   <xs:element name="and" type="filterGroupAndType" minOccurs="0"/>
   <xs:element name="filterElement" type="filterType" minOccurs="0"/>
  </xs:sequence>
 </xs:complexType>
 <xs:complexType name="filterType">
  <xs:attribute name="argument" type="xs:string" use="required"/>
  <xs:attribute name="operator" type="operatorSimpleType" use="required"/>
  <xs:attribute name="value" type="xs:anySimpleType"/>
  <xs:attribute name="field" type="fieldTitleSimpleType"/>
 </xs:complexType>

提前致谢。

3 个答案:

答案 0 :(得分:3)

简言之

  1. 文档有效,因为元素有minOccurs="0"
  2. 使用<xs:choice>代替<xs:sequence>
  3. 答案稍长。

    就像@Damien所说,XML是有效的,因为你的架构的这一部分允许“空”序列。

    <xs:sequence minOccurs="2" maxOccurs="unbounded">
      <xs:element name="or" type="filterGroupOrType" minOccurs="0"/>
      <xs:element name="filterElement" type="filterType" minOccurs="0"/>
    </xs:sequence>
    

    使用<xs:sequence minOccurs="2" maxOccurs="unbounded">您可以定义“此序列必须至少出现两次”。同时<xs:element name="or" type="filterGroupOrType" minOccurs="0"/>允许序列中的这些元素不存在。隐喻地说,“你必须订两次饭,但你不必吃任何你订的饭。”

    相反,如果您希望始终拥有至少2个子元素,并且这些子元素可以是任意顺序的<filterElement><or>个元素,那么您应该<xs:choice>使用minOccurs="1"

    <xs:choice minOccurs="2" maxOccurs="unbounded">
      <xs:element name="or" type="filterGroupOrType" minOccurs="1"/>
      <xs:element name="filterElement" type="filterType" minOccurs="1"/>
    </xs:choice>
    

    minOccurs的默认值为1,因此您可以将其保留,并使代码更清晰,更短。 <xs:choice>选择其中一个子项并重复选择至少minOccurs次。如果至少有一个选项可以minOccurs="0",则选择也将允许“空”选择。

答案 1 :(得分:2)

filterElement上有一个minOccurs =“0”。因此,单个filterElement可以被视为filterElement的0次,后面是filterElement。一个有效的序列。 也许你应该避免在你的模式中混合xs:sequence和xs:element中的minOccurs ......

答案 2 :(得分:0)

您的序列必须出现两次,但序列中的元素是可选的(minOccurs =“0”)。序列本身并不代表任何XML,它只是定义它可以包含的可能元素以及它们必须包含的顺序。在这种情况下,完全有效的序列可以为空。

更换&lt; xs:sequence&gt;与&lt; xs:choice&gt;如果你不关心元素出现在哪个顺序而且你看起来没有,那么将子元素上的minOccurs更改为1将会起作用。如果没有在子项上将minOccurs设置为1,则有效选择仍然是0次出现的元素,并且您的XML将进行验证。如果你在子元素上将minOccurs设置为2,那么你将至少有4个元素,因为你可以选择两次并从每次出现两次的每个子元素中选择。