XSD - Как описать неупорядоченный набор типов элементов, где первый элемент должен появиться первым в последовательности?
Это вопрос схемы 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>
Мой вопрос заключается в том, как объявить элементы "ADD" и "DELETE" выше в любом порядке (неупорядоченный набор), но все же убедитесь, что элемент "Имя" будет первым и всегда появится. (Подумайте о ситуации, когда у меня есть не только "ADD" и "DELETE", но и 10 или более неупорядоченных элементов: ADD, DELETE, EDIT и т.д.)
ВАЖНОЕ ПРИМЕЧАНИЕ: ADD и DELETE могут появляться только один раз, но их порядок не имеет значения:
<Application>
<NAME>
<DELETE>
<ADD>
</Application>
но NOT:
<Application>
<NAME>
<DELETE>
<ADD>
<DELETE> <!--cannot appear twice-->
</Application>
Ответы
Ответ 1
Если я понимаю ваш запрос, вы правы на своем пути, единственное, что вам не хватает, - 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>
Ответ 2
Я думаю, что вы ищете элемент "все", он позволяет использовать неупорядоченный список. Однако есть ограничения на элементы, которые вы можете поместить там. См. http://www.w3.org/2005/07/xml-schema-patterns.html#Collection
Ответ 3
Мне жаль, что вы работали с этой проблемой уже 7 лет без ответа.
Я собираюсь помочь, пересмотрев ваши предположения.
Обращаясь к "Name" как к части данных, которая должна быть первой, и требуя, чтобы она была дочерью приложения, а затем, в общем говоря, вы не заботитесь о порядке своих братьев и сестер, вы делаете смущающая ситуация для вас самих. Почему Name является дочерним агентом ADD и DELETE, если он соответствует различным правилам и служит другой цели? Если бы вам пришлось моделировать это в любой другой структуре данных, вы не включали бы "Имя" в список вещей наряду с "ДОБАВИТЬ" и "УДАЛИТЬ". Вы могли бы сказать две вещи: приложение имеет имя, а также имеет список таких команд, как ADD и DELETE.
Так как Name является особой вещью по сравнению с ADD и DELETE, то он должен быть смоделирован отдельно от других тегов.
Таким образом, вы можете либо сделать Name атрибутом приложения, либо сохранить Add и Delete в качестве дочерних элементов, или вы можете сохранить Name в качестве дочернего элемента, а затем окружать ADD и DELETE тегом placeholder/grouping, таким как Commands. Тег "Команды" будет единственным родственником имени.
Здесь схема, поддерживающая Name как атрибут, с произвольным количеством команд в любом порядке. "Name as Attribute.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>
И здесь один с командами, вложенными в тег placeholder. "Команды 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>
Одна из примечаний о любом из них заключается в том, что сообщения с нулевыми командами остаются действительными. Возможно, это хорошо, но если это проблема, возможно, эта проверка относится к слою Application, а не к XSD.
Ответ 4
Я не считаю, что это можно сделать без перечисления каждой комбинации ADD, DELETE и т.д. Вообще говоря, неупорядоченные списки плохо воспроизводятся с DTD или схемами.
Ответ 5
Вы можете реализовать неупорядоченные списки, используя тип последовательности 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/>
так часто, как им нравится.