Проверка схемы XML. Неупорядоченный список с неопределенным количеством элементов - PullRequest
0 голосов
/ 28 октября 2019

Я пытаюсь создать схему XML для проверки следующего XML с использованием версии 1.0.

Правила:

  1. XML неупорядочен в теге <host>
  2. ip4, present и hostname являются обязательными обязательными
  3. comment не требуются
  4. Может быть любое количество элементов hostname

example.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>

У меня сейчас есть ...

example.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>

Но я не могу обойтись без какого-либо количества элементов имени хоста.

1 Ответ

1 голос
/ 29 октября 2019

Для начала ваш XSD даже недействителен, <xs:element> перед </xs:schema> должно быть </xs:element>

Но да, вы не можете заставить имя хоста встречаться несколько раз в xsd:Все. В Visual Studio (с BizTalk SDK) я получаю следующую ошибку:

Число {макс происходит} всех частиц в {частице} всей группы должно быть 0 или 1.

У вас есть два варианта. Либо измените хост на выбор с minOccurs 3 и maxOccurs unbounded. Это, однако, не приведет к тому, что ваш ip4, имя хоста и подарок будут появляться как минимум один раз и только один раз для ip и present.

Другой вариант - изменить структуру вашей полезной нагрузки и иметь узел hostnames, под которым выиметь элемент hostname и установить для него значение 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>
...