【问题标题】:XMLSpy ignores "minOccurs"? Why is this XML valid?XMLSpy 忽略“minOccurs”?为什么这个 XML 有效?
【发布时间】:2010-09-08 13:56:30
【问题描述】:

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

提前致谢。

【问题讨论】:

  • 遗憾的是,XMLSpy 认为有很多事情是有效的,但实际上并非如此。 XMLSpy 非常糟糕。
  • 正是出于这个原因,他应该尝试使用 w3c 验证器...
  • @Forlan07 您能否提供 w3c 验证器的链接以使用模式进行验证?我只发现了一些实验性的东西和 DTD 验证。谢谢!

标签: xml xsd xmlspy


【解决方案1】:

简述

  1. 文档有效,因为元素具有minOccurs="0"
  2. 使用&lt;xs:choice&gt; 而不是&lt;xs:sequence&gt;

一个更长的答案。

就像@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>

使用&lt;xs:sequence minOccurs="2" maxOccurs="unbounded"&gt;,您定义“此序列必须至少出现两次”。同时&lt;xs:element name="or" type="filterGroupOrType" minOccurs="0"/&gt;允许序列内的这些元素不存在。打个比方,这就像说“您必须点两次餐,但您不必吃任何您点的餐。”

相反,如果您希望始终拥有至少 2 个子元素并且这些子元素可以是&lt;filterElement&gt;&lt;or&gt; 元素的任意顺序,您应该使用&lt;xs:choice&gt;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,因此您可以省略它并保持代码更简洁。 &lt;xs:choice&gt; 选择它的一个孩子并重复选择至少minOccurs 次。如果至少有一个选项可以有minOccurs="0",那么该选项也将允许“空”选项。

【讨论】:

  • 感谢您提供的非常好的解释。如上所述,我没有更改 xs:choice 和 xs:element 的 minOccurs。这达到了我想要的效果:任意两个或更多,以任意顺序。
  • filterElementor 在您的架构中仍然有 minOccurs="0" 吗?如果是这样,那么即使您使用 &lt;xs:choice minOccurs="2"&gt;,您的原始文档仍然有效(您不希望发生这种情况),因为元素定义上的 minOccurs="0" 允许验证器选择元素 0 次。
【解决方案2】:

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

【讨论】:

  • 我将结构更改为 xs:choice 并且它起作用了。不过,我不明白你的解释。我将对这些构造函数进行一些阅读。谢谢!
【解决方案3】:

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

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

【讨论】:

  • 也感谢您的回答!我现在真正了解 xs:choice 的微妙之处,这很有帮助。
猜你喜欢
  • 2020-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-09
  • 2014-08-10
相关资源
最近更新 更多