Имя XSD-неизвестные необязательные элементы с известными по имени необязательными элементами

#xsd

#xsd

Вопрос:

Начиная с годичной разработки XSD / XML, я хочу написать более простой XSD, предназначенный только для элементов, которые не будут изменены или удалены, который может проверять XML из полного XSD.

Чтобы упростить:

С помощью этого XML:

 <root>
    <unknown1/>
    <known2/>
    <unknown2/>
    <known1/>
    <unknown3/>
    <unknown4/>
</root>
  

И этот XSD:

 <xsd:schema>
    <xsd:element name="root">
        <xsd:all>
            <xsd:element name="unknown1"  minOccurs="0"/>
            <xsd:element name="unknown2" minOccurs="0"/>
            <xsd:element name="unknown3" minOccurs="0"/>
            <xsd:element name="unknown4" minOccurs="0"/>
            <xsd:element name="known1" minOccurs="0"/>
            <xsd:element name="known2" minOccurs="0"/>
        </xsd:all>
    </xsd:element name="root">
</xsd:schema>
  

Я хочу сделать что-то вроде:

 <xsd:schema>
    <xsd:all>
        <xsd:any processControl="skip" />
        <xsd:element name="known1" />
        <xsd:element name="known2" />
</xsd:schema>
  

Этот XSD недопустим, поскольку xsd:any может отображаться только в xsd:sequence или xsd:choice

Интересно, как я могу проверить исходный XML-файл с помощью аналогичного простого XSD

Ответ №1:

Вы можете создать xs:choice из known1, 2 и xs:any и установить maxOccurs в unbounded .

Редактировать: Это по-прежнему обрабатывает только необязательный регистр, но я понял, что вам не обязательно вставлять xs:choice в xs:sequence .

Комментарии:

1. а что, если я получу XML без know1 и / или know2? это подтвердит, и это будет неверно

2. итак, known1 и known2 обязательны, но остальные необязательны? в заголовке говорится «Неизвестные по имени необязательные элементы с известными по имени необязательными элементами», поэтому я в замешательстве.

3. Мои извинения, они необязательны. что вы порекомендуете из необязательных элементов? И даже с необязательным элементом, если у меня есть known1 amp; known2 плюс дополнительные элементы (например, unknown1), это не приведет к правильному результату

4. Если использование XML-схемы не является обязательным, вы могли бы попробовать Relax NG, в котором есть концепция чередования и класс имен .

5. К сожалению, это требование

Ответ №2:

Вот рабочая схема, которая позволяет

  • свободный порядок между <known1> и <known2> элементами
  • пропуск <known1> или <known2> (или обоих)
  • неограниченное количество любых других элементов до, после или между ними

Обратите внимание, что вы должны ограничить элементы, разрешенные <xs:any> некоторым другим пространством имен, чем <known1> или <known2> . В противном случае схема станет однозначной, потому что <xs:any> также разрешит <known1> или <known2> . Еще одна вещь, на которую следует обратить внимание, это то, что здесь нам иногда нужно установить minOccurs атрибут в <xs:choice> или <xs:sequence> , чтобы сохранить детерминированность схемы.

 <xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="root">
    <xs:complexType>
      <xs:sequence>
        <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other" processContents="skip" />
        <xs:choice minOccurs="0">
          <xs:sequence>
            <xs:element name="known1" />
            <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other" processContents="skip" />
            <xs:sequence minOccurs="0">
              <xs:element name="known2" />
              <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other" processContents="skip" />
            </xs:sequence>
          </xs:sequence>
          <xs:sequence>
            <xs:element name="known2" />
            <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other" processContents="skip" />
            <xs:sequence minOccurs="0">
              <xs:element name="known1" />
              <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other" processContents="skip" />
            </xs:sequence>
          </xs:sequence>
        </xs:choice>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>
  

Ответ №3:

Короткий ответ: используйте XSD 1.1

Тогда ваше предложение сработает. Более конкретно:

 <?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" elementFormDefault="qualified" attributeFormDefault="unqualified" vc:minVersion="1.1">

    <xs:element name="root" type="root"/>

    <xs:complexType name="root">
        <xs:all>
            <!-- Required -->
            <xs:element name="known1" type="xs:string"/>
            <!-- Optional -->
            <xs:element name="known2" type="xs:string" minOccurs="0"/>
            <xs:element name="known3" type="xs:string" minOccurs="0"/>
            <!-- Unknown -->
            <xs:any minOccurs="0" maxOccurs="unbounded" processContents="skip"/>
        </xs:all>
    </xs:complexType>

</xs:schema>