Игнорировать порядок элементов с помощью xs: extension
Как я могу создать xsd для игнорирования последовательности элементов?
<root> <a/> <b/> </root>
<root> <b/> <a/> </root>
Мне нужно использовать extension
для причин генерации кода, поэтому я попробовал использовать all
:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.example.com/test"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:t="http://www.example.com/test" >
<xs:complexType name="BaseType">
<xs:all>
<xs:element name="a" type="xs:string" />
</xs:all>
</xs:complexType>
<xs:complexType name="ExtendedType">
<xs:complexContent>
<xs:extension base="t:BaseType">
<xs:all> <!-- ERROR -->
<xs:element name="b" type="xs:string" />
</xs:all>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="root" type="t:ExtendedType"></xs:element>
</xs:schema>
Этот xsd недействителен, хотя в <!-- ERROR -->
сообщается следующая ошибка:
cos-all-limited.1.2: вся модельная группа должна появиться в частице с {min встречается} = {max встречается} = 1, и эта частица должна быть частью пары, которая составляет {тип контента} определение сложного типа.
Документация cos-all-limited.1.2 гласит:
1.2 свойство {term} частицы с {max встречается} = 1, которое является частью пары, которая составляет {тип содержимого} определения сложного типа.
Я действительно не понимаю этого (ни xsd, ни английский носитель:)).
Я делаю не то, что я делаю неправильно, или нет способа добиться этого?
Ответы
Ответ 1
ОСНОВНОЕ ИЗОБРАЖЕНИЕ Первоначально я пропустил требование, которое вам нужно использовать xsd:extension
. Обратите внимание, что xsd:extension
работает так, как будто было xsd:sequence
с содержимым базового типа, за которым следует содержимое расширенного типа. Как пишет XML-схема Primer:
Когда сложный тип получается расширение, его эффективная модель контента является моделью контента базового типа плюс модель контента, указанная в тип вывода. Кроме того, две модели контента рассматриваются как два дети последовательной группы.
Следовательно, кажется, что единственный способ сделать эту работу - иметь пустой базовый тип и хранить всю альтернативу в расширенном типе, или наоборот (все в базе и пустое расширение). Вот так:
<xsd:complexType name="ExtendedType">
<xsd:complexContent>
<xsd:extension base="BaseType">
<xsd:choice>
<xsd:sequence>
<xsd:element name="a" type="xsd:string"/>
<xsd:element name="b" type="xsd:string"/>
</xsd:sequence>
<xsd:sequence>
<xsd:element name="b" type="xsd:string"/>
<xsd:element name="a" type="xsd:string"/>
</xsd:sequence>
</xsd:choice>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="BaseType"/>
<xsd:element name="root" type="ExtendedType"/>
Ответ 2
Вот объяснение ограничения:
http://marc.info/?l=xerces-j-user&m=118712527901786&w=4
Единственным расширением, которое вы можете сделать для сложного типа с помощью модели "все", является добавление некоторых атрибутов. Вы не можете распространяться на новые элементы.
В моем случае я сделал что-то вроде этого:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.example.com/test"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:t="http://www.example.com/test" >
<xs:complexType name="BaseType">
<xs:all>
<xs:element name="a" type="xs:string" />
</xs:all>
</xs:complexType>
<xs:complexType name="ExtendedType">
<xs:all>
<xs:element name="a" type="xs:string" /> <!-- copy/paste from BaseType -->
<xs:element name="b" type="xs:string" />
</xs:all>
</xs:complexType>
<xs:element name="root" type="t:ExtendedType"></xs:element>
</xs:schema>
Ответ 3
<xs:complexType name="BaseType">
<xs:sequence>
<xs:element name="a" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="ExtendedType">
<xs:complexContent>
<xs:extension base="t:BaseType">
<xs:sequence>
<xs:element name="b" type="xs:string" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="root" type="t:ExtendedType"></xs:element>