XSD 用于至少一个元素的可选列表?

Posted

技术标签:

【中文标题】XSD 用于至少一个元素的可选列表?【英文标题】:XSD for optional list of at least one element? 【发布时间】:2021-12-26 00:55:09 【问题描述】:

我想确保<specials/> 可以是可选的,但是当它发生时,我想确保它至少有一个<special>

想象一下下面的 XML:

<software>
  <programm id="123">
    <name>Editor</name>
    <specials>
      <special>Something really special here</special>
      <special>Something special as well</special>
    </specials>
  </programm>
  <programm id="456">
    <name>Another Editor</name>
  </programm>
</software>

我为此尝试过的 XSD 是。如果只有 &lt;specials&gt;&lt;/specials&gt; 但里面没有孩子,这不会引发验证错误。

<xs:element name="software">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="programm" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="name" type="xs:string" minOccurs="1"/>
                        <xs:element name="specials" minOccurs="0">
                            <xs:complexType>
                                <xs:sequence minOccurs="1">
                                    <xs:element name="special" type="xs:string" minOccurs="1"/>
                                </xs:sequence>
                            </xs:complexType>
                        </xs:element>
                    </xs:sequence>
                    <xs:attribute name="id" type="programmID"/>
                </xs:complexType>
            </xs:element>
       </xs:sequence>
    </xs:complexType>
</xs:element>

【问题讨论】:

当我删除 special 元素并使用空的 special 元素进行验证时,它会报告验证错误:The content of element 'specials' is not complete. One of 'special' is expected 【参考方案1】:

至少一个member 元素的可选list 元素的XSD 约束可以简单地用minOccursmaxOccurs 表示:

          <xs:element name="list" minOccurs="0">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="member" maxOccurs="unbounded"/>
              </xs:sequence>
            </xs:complexType>
          </xs:element>

如果只有&lt;specials&gt;&lt;/specials&gt; 但里面没有孩子,这不会引发验证错误。

相反,您编写的 XSD 将无法根据需要验证带有空 specials 元素的 XML,因为它指定 specials 是可选的,但当存在时,它的 special 子元素必须出现一次。除了这个分析观察之外,我还通过实际验证凭经验证实了这种行为。

旁注:

minOccurs="1" 是默认设置,因此您可以在整个 XSD 中删除它们。

maxOccurs="1" 是默认值,因此您可能希望special 上的maxOccurs="unbounded" 允许在specials 内重复。

您不需要在此处对xs:sequence 进行出现限制。除了 minOccurs="1" 已经是默认值之外,无论如何,序列中只有一个孩子,因此没有必要(并且可能会分散注意力)指定一组出现约束。

这是一个完整的 XSD,它包含上述注释并验证您的 XML:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified">
  <xs:element name="software">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="programm" minOccurs="0" maxOccurs="unbounded">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="name" type="xs:string"/>
              <xs:element name="specials" minOccurs="0">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="special" maxOccurs="unbounded"/>
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
            <xs:attribute name="id" type="xs:string"/>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

另见

XML Schema minOccurs / maxOccurs default values

【讨论】:

以上是关于XSD 用于至少一个元素的可选列表?的主要内容,如果未能解决你的问题,请参考以下文章

在XSD中,当可选的父元素出现时,它的子元素是必需的吗?

ListView 中的可选 TextView(缺少动画)

Terraform 中的可选变量在值为 null 时不会被忽略

Oracle 10g 中的可选条件

序列中的可选元素

附加 DOM 元素不适用于 jQuery 可选