首页 > 解决方案 > XSD 1.0:如何以任意顺序验证 4 个元素,每个元素只出现一次,但至少其中一个元素必须只出现一次

问题描述

我的情况如下:

  1. 我有 4 个不同的元素可以按任何顺序出现
  2. 这 4 个元素中的每一个元素最多只能出现一次。也就是0或1次。
  3. 必须至少出现这 4 个元素中的一个。

遗憾的是,我只能使用 .NET Framework 类来处理 Schema,这意味着我正在寻找使用 XSD 1.0 的解决方案。

这是一些显然不起作用的示例 XML!

<xs:complexType name="Groups">
<xs:sequence>
  <xs:element name="Group1" type="group1" minOccurs="0" maxOccurs="1" />
  <xs:element name="Group2" type="group2" minOccurs="0" maxOccurs="1" />
  <xs:element name="Group3" type="group3" minOccurs="0" maxOccurs="1" />
  <xs:element name="Group4" type="group4" minOccurs="0" maxOccurs="1" />
 </xs:sequence></xs:complexType>

标签: xmlxsdschemaxsd-validation

解决方案


您需要将 替换为<xs:sequence><xs:all>这将

  1. 允许 Group# 节点的任何顺序
  2. 允许每个元素出现最大值为 1

下面唯一没有验证的是至少出现了 1 个元素。

    <xs:element name="Groups">
      <xs:complexType>
        <xs:all>
          <xs:element minOccurs="0" maxOccurs="1" name="Group1" type="Group1" />
          <xs:element minOccurs="0" maxOccurs="1" name="Group2" type="Group2" />
          <xs:element minOccurs="0" maxOccurs="1" name="Group3" type="Group3" />
          <xs:element minOccurs="0" maxOccurs="1" name="Group4" type="Group4" />
        </xs:all>
      </xs:complexType>
    </xs:element>

如果你真的想验证至少有 1 个元素出现在它之后的任何元素组合中,它就会变成一个非常复杂的大型模式,其中包含很多选择和序列节点,并且在各个地方将 minOccurs 设置为 0。以下架构将验证以 Group1 开头的任何文件以及其他组的任何组合。

<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns="http://Scratch.SO57321841" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" targetNamespace="http://Scratch.SO57321841" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Root">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Groups">
          <xs:complexType>
            <xs:choice minOccurs="1">
              <xs:sequence>
                <xs:element name="Group1" type="Group1" />
                <xs:choice minOccurs="0">
                  <xs:sequence>
                    <xs:element name="Group2" type="Group2" />
                    <xs:choice minOccurs="0">
                      <xs:sequence>
                        <xs:element name="Group3" type="Group3" />
                        <xs:element minOccurs="0" name="Group4" type="Group4" />
                      </xs:sequence>
                      <xs:sequence>
                        <xs:element name="Group4" type="Group4" />
                        <xs:element minOccurs="0" name="Group3" type="Group3" />
                      </xs:sequence>
                    </xs:choice>
                  </xs:sequence>
                  <xs:sequence>
                    <xs:element name="Group3" type="Group3" />
                    <xs:choice minOccurs="0">
                      <xs:sequence>
                        <xs:element name="Group2" type="Group2" />
                        <xs:element minOccurs="0" name="Group4" type="Group4" />
                      </xs:sequence>
                      <xs:sequence>
                        <xs:element name="Group4" type="Group4" />
                        <xs:element minOccurs="0" name="Group2" type="Group2" />
                      </xs:sequence>
                    </xs:choice>
                  </xs:sequence>
                  <xs:sequence>
                    <xs:element name="Group4" type="Group4" />
                    <xs:choice minOccurs="0">
                      <xs:sequence>
                        <xs:element name="Group2" type="Group2" />
                        <xs:element minOccurs="0" name="Group3" type="Group3" />
                      </xs:sequence>
                      <xs:sequence>
                        <xs:element name="Group3" type="Group3" />
                        <xs:element minOccurs="0" name="Group2" type="Group2" />
                      </xs:sequence>
                    </xs:choice>
                  </xs:sequence>
                </xs:choice>
              </xs:sequence>
              <xs:sequence>
                <xs:element name="Group2" type="Group2" />
                <xs:choice minOccurs="0" />
              </xs:sequence>
              <xs:sequence>
                <xs:element name="Group3" type="Group3" />
                <xs:choice minOccurs="0" />
              </xs:sequence>
              <xs:sequence>
                <xs:element name="Group4" type="Group4" />
                <xs:choice minOccurs="0" />
              </xs:sequence>
            </xs:choice>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:complexType name="Group1" />
  <xs:complexType name="Group2" />
  <xs:complexType name="Group3" />
  <xs:complexType name="Group4" />
</xs:schema>

推荐阅读