XSD - Как описать неупорядоченный набор типов элементов, где первый элемент должен появляться первым в последовательности? - PullRequest
18 голосов
/ 06 января 2009

Это вопрос схемы XML.

Я знаю, что элемент xsd:all не может появляться в последовательности (должен быть элементом верхнего уровня своего типа).

То есть я не могу использовать следующее:

<xsd:complexType name="Application">
  <xsd:sequence>
    <xsd:element ref="Name"></xsd:element>
    <xsd:all>
      <xsd:element ref="ADD"></xsd:element>
      <xsd:element ref="DELETE"></xsd:element>
    </xsd:all>
  </xsd:sequence>
</xsd:complexType>

Мой вопрос заключается в том, как объявить элементы «ДОБАВИТЬ» и «УДАЛИТЬ» выше в любом порядке (неупорядоченный набор), но при этом убедиться, что элемент «Имя» будет первым и всегда будет отображаться. (Вспомните ситуацию, когда у меня есть не только «ДОБАВИТЬ» и «УДАЛИТЬ», но и установить около 10 или более неупорядоченных элементов: ДОБАВИТЬ, УДАЛИТЬ, РЕДАКТИРОВАТЬ и т. Д.

ВАЖНОЕ ПРИМЕЧАНИЕ: ДОБАВИТЬ и УДАЛИТЬ могут появиться только ОДИН РАЗ, но их порядок не имеет значения:

<Application>
  <NAME>
   <DELETE>
   <ADD>
</Application>

но НЕ:

<Application>
  <NAME>
  <DELETE>
  <ADD>
  <DELETE> <!--cannot appear twice-->
</Application>

Ответы [ 5 ]

17 голосов
/ 06 января 2009

Если я понимаю ваш запрос, вы не ошиблись, единственное, чего вам не хватает, это maxOccurs = "неограниченный" по вашему выбору.

Я создал следующую схему:

<?xml version="1.0"?>
<xs:schema targetNamespace="http://someNamespace" xmlns="http://someNamespace" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Root" type="Application">
  </xs:element>

  <xs:complexType name="Application">
    <xs:sequence>
      <xs:element ref="Name"></xs:element>
      <xs:choice maxOccurs="unbounded">
        <xs:element ref="ADD"></xs:element>
        <xs:element ref="DELETE"></xs:element>
      </xs:choice>
    </xs:sequence>
  </xs:complexType>

  <xs:element name="Name"/>
  <xs:element name="ADD"/>
  <xs:element name="DELETE"/>
</xs:schema>

И это хорошо работало для

<ns0:Root xmlns:ns0="http://someNamespace">
  <ns0:Name />
  <ns0:ADD />
  <ns0:ADD />
  <ns0:DELETE />
  <ns0:ADD />
  <ns0:DELETE />
  <ns0:DELETE />
</ns0:Root>

но не для

<ns0:Root xmlns:ns0="http://someNamespace">
  <ns0:ADD />
  <ns0:ADD />
  <ns0:DELETE />
  <ns0:ADD />
  <ns0:DELETE />
  <ns0:DELETE />
</ns0:Root>
4 голосов
/ 06 июня 2016

Мне жаль, что вы уже 7 лет трудитесь над этой проблемой, но без ответа.

Я собираюсь помочь, пересмотрев ваши предположения.

Обрабатывая «Имя» как часть данных, которая должна идти первой, и требуя, чтобы она была дочерней по отношению к Приложению, а затем в общем говоря, что вы не заботитесь о порядке своих братьев и сестер, вы делаете запутанная ситуация для себя. Почему Name является родным братом ADD и DELETE, если он следует другим правилам и служит другой цели? Если бы вам пришлось смоделировать это в любой другой структуре данных, вы бы не включили «Имя» в список вещей наряду с «ДОБАВИТЬ» и «УДАЛИТЬ». Вы бы сказали две вещи: у приложения есть имя, а также список команд, таких как ADD и DELETE.

Поскольку имя - это особенная вещь по сравнению с ДОБАВИТЬ и УДАЛИТЬ, то его следует моделировать отдельно от других тегов.

Таким образом, вы можете либо сделать Name атрибутом Application, и оставить Add и Delete в качестве дочерних элементов, либо вы можете оставить Name в качестве дочернего элемента, но затем окружить ADD и DELETE тегом-заполнителем / группировкой, например Commands. Тег Commands будет единственным братом Name.

Вот схема, поддерживающая Name в качестве атрибута с произвольным количеством команд в любом порядке. «Имя как атрибут.xsd»:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="Application" type="Application_Type" />
    <xs:complexType name="Application_Type">
            <xs:all>
                <xs:element minOccurs="0" ref="ADD"/>
                <xs:element minOccurs="0" ref="DELETE"/>
                <xs:element minOccurs="0" ref="THIRD"/>
                <xs:element minOccurs="0" ref="FOURTH"/>
            </xs:all>
            <xs:attribute name="Name"/>
    </xs:complexType>
    <xs:element name="ADD"/>
    <xs:element name="DELETE"/>
    <xs:element name="THIRD"/>  
    <xs:element name="FOURTH"/> 
</xs:schema>

Пример XML:

<?xml version="1.0" encoding="UTF-8"?>
<Application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="text" xsi:noNamespaceSchemaLocation="Name as Attribute.xsd">
    <THIRD>text</THIRD>
    <ADD>text</ADD>
    <FOURTH>text</FOURTH>
    <DELETE>text</DELETE>
</Application>

И вот одна из них с командами, вложенными в тег-заполнитель. "Commands Grouping.xsd":

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="Application" type="Application_Type"/>
    <xs:complexType name="Application_Type">
        <xs:sequence>
            <xs:element ref="Name"/>
            <xs:element name="Commands" type="Commands_Type"/>
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="Commands_Type">
        <xs:all>
            <xs:element minOccurs="0" ref="ADD"/>
            <xs:element minOccurs="0" ref="DELETE"/>
            <xs:element minOccurs="0" ref="THIRD"/>
            <xs:element minOccurs="0" ref="FOURTH"/>
        </xs:all>
    </xs:complexType>
    <xs:element name="Name"/>
    <xs:element name="ADD"/>
    <xs:element name="DELETE"/>
    <xs:element name="THIRD"/>
    <xs:element name="FOURTH"/>
</xs:schema>

Пример XML:

<?xml version="1.0" encoding="UTF-8"?>
<Application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Commands Grouping.xsd">
    <Name>text</Name>
    <Commands>
        <THIRD>text</THIRD>
        <ADD>text</ADD>
        <FOURTH>text</FOURTH>
        <DELETE>text</DELETE>
    </Commands>
</Application>

Одно замечание по поводу любого из них заключается в том, что сообщения с нулевыми командами по-прежнему являются действительными сообщениями. Возможно, это нормально, но если это проблема, возможно, проверка относится к прикладному уровню, а не к XSD.

4 голосов
/ 05 февраля 2010

Я думаю, что вы ищете элемент "all", он допускает неупорядоченный список. Однако существуют ограничения на элементы, которые вы можете поместить туда. Смотри http://www.w3.org/2005/07/xml-schema-patterns.html#Collection

3 голосов
/ 08 января 2009

Я не верю, что это можно сделать без перечисления каждой комбинации ADD, DELETE и т. Д. Вообще говоря, неупорядоченные списки не очень хорошо работают с DTD или схемами.

1 голос
/ 26 ноября 2014

Вы можете реализовать неупорядоченные списки, используя тип последовательности xs:choice.

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xs:element name="Application"/>
  <xs:complexType>
   <xs:element name="NAME">
    <xs:sequence>
     <xs:choice minOccurs="0" maxOccurs="unbounded">
      <xs:element name="ADD" type="xs:string"/>
      <xs:element name="DELETE" type="xs:string"/>
     </xs:choice>
    </xs:element>
   </xs:sequence>
  </xs:complexType>
 </xs:element>
</xs:schema>

Таким образом, вы ограничиваете пользователя от использования любого тега, который он хочет внутри элемента <NAME/>, но разрешаете ему использовать <ADD/> и <DELETE/> так часто, как ему нравится.

...