1

请告诉我为什么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>

提前致谢。

4

3 回答 3

3

简要地

  1. 文档是有效的,因为元素有minOccurs="0".
  2. 使用<xs:choice>而不是<xs:sequence>.

长一点的回答。

就像@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>withminOccurs="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>

的默认值为minOccurs1,因此您可以将其省略并保持代码更简洁。<xs:choice>选择它的一个孩子并重复选择至少minOccurs几次。如果至少有一个选择可以,minOccurs="0"那么该选择也将允许“空”选择。

于 2010-09-10T17:13:54.240 回答
2

您在 filterElement 上有一个 minOccurs="0"。所以单个filterElement可以看成一个filterElement 0次,后面跟着一个filterElement。一个有效的序列。也许您应该避免在架构中的 xs:sequence 和 xs:element 中混合 minOccurs ...

于 2010-09-08T15:06:53.893 回答
0

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

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

于 2010-09-10T17:46:53.983 回答