首页 > 解决方案 > XML 模式验证。项目数不定的无序列表

问题描述

我正在尝试使用 1.0 版创建用于验证以下 XML 的 XML 模式。

规则是

  1. <host>XML 在标签下是无序的
  2. ip4, present, 和hostname必需的
  3. comment不需要
  4. 可以有任意数量的hostname元素

例子.xml

<?xml version = "1.0"?>
<host>
  <comment>List of hosts</comment>
  <hostname>nohostname1</hostname>
  <hostname>nohostname2</hostname>
  <ipv4>127.0.0.1</ipv4>
  <present>no</present>
</host>

我目前有...

例子.xsd

<?xml version = "1.0"?>
<xs:schema xmlns:xs = "http://www.w3.org/2001/XMLSchema">
<!-- any_string_type -->
<xs:simpleType name="any_string_type">
  <xs:restriction base="xs:string"/>
</xs:simpleType>

<!-- boolean_type -->
<xs:simpleType name="boolean_value_type">
  <xs:annotation>
    <xs:documentation>Boolean annotation [no/yes]</xs:documentation>
  </xs:annotation>
  <xs:restriction base="xs:string">
      <xs:enumeration value="no"/>
      <xs:enumeration value="yes"/>
  </xs:restriction>
</xs:simpleType>

<!-- ipv4 address type -->
<xs:simpleType name="ipv4_type">
  <xs:annotation>
    <xs:documentation>IPv4 address in dot-decimal notation [0-255].[0-255].[0-255].[0-255]</xs:documentation>
  </xs:annotation>
  <xs:restriction base="xs:string">
    <xs:pattern value="((1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.){3}(1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])"/>
  </xs:restriction>
</xs:simpleType>


<!-- Start of host validation -->
<xs:element name = "host">
    <xs:complexType>
        <xs:all>
          <xs:element name = "ipv4" type = "ipv4_type"/>
          <xs:element name = "comment" type = "any_string_type" minOccurs="0"/>
          <xs:element name = "present" type = "boolean_value_type"/>

          <!-- I want to say maxOccures="unbounded" but that is not valid XML schema -->
          <xs:element name = "hostname" type = "any_string_type"/> 

        </xs:all>
    </xs:complexType>
</xs:element>
</xs:schema>

但我似乎无法解决任何数量的主机名元素。

标签: xmlxsdxsd-validation

解决方案


对于初学者来说,您的 XSD 甚至无效,<xs:element>就在之前</xs:schema>应该是</xs:element>

但是,是的,您不能让主机名在 xsd:All 中出现多次。在 Visual Studio(使用 BizTalk SDK)中,我收到以下错误。

一个 all 组的 {particle} 中的所有粒子的 {maxoccurrence} 必须为 0 或 1。

你有两个选择。要么将主机更改为 minOccurs 为 3 且 maxOccurs 无界的选项。但是,这不会强制您的 ip4、主机名和存在至少出现一次,并且对于 ip 和存在仅出现一次。

另一种选择是更改有效负载的结构并拥有一个主机名节点,在该节点下您拥有主机名元素并将其设置为 minOccurs="1" 和 maxOccurs="unbounded"

<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns:b="http://schemas.microsoft.com/BizTalk/2003" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:simpleType name="any_string_type">
    <xs:restriction base="xs:string" />
  </xs:simpleType>
  <xs:simpleType name="boolean_value_type">
    <xs:annotation>
      <xs:documentation>Boolean annotation [no/yes]</xs:documentation>
    </xs:annotation>
    <xs:restriction base="xs:string">
      <xs:enumeration value="no" />
      <xs:enumeration value="yes" />
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="ipv4_type">
    <xs:annotation>
      <xs:documentation>IPv4 address in dot-decimal notation [0-255].[0-255].[0-255].[0-255]</xs:documentation>
    </xs:annotation>
    <xs:restriction base="xs:string">
      <xs:pattern value="((1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.){3}(1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])" />
    </xs:restriction>
  </xs:simpleType>
  <xs:element name="host">
    <xs:complexType>
      <xs:all minOccurs="1" maxOccurs="1">
        <xs:element name="ipv4" type="ipv4_type" />
        <xs:element minOccurs="0" name="comment" type="any_string_type" />
        <xs:element name="present" type="boolean_value_type" />
        <xs:element name="hostnames">
          <xs:complexType>
            <xs:sequence>
              <xs:element minOccurs="1" maxOccurs="unbounded" name="hostname" type="any_string_type" />
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:all>
    </xs:complexType>
  </xs:element>
</xs:schema>

有效载荷看起来像这样并进行验证。

<?xml version = "1.0"?>
<host>
  <comment>List of hosts</comment>
  <hostnames>
      <hostname>nohostname1</hostname>
      <hostname>nohostname2</hostname>
  </hostnames>
  <ipv4>127.0.0.1</ipv4>
  <present>no</present>
</host>

推荐阅读