XSD условное присвоение типа путаница по умолчанию?
Я пытаюсь разработать XSD с CTA. У меня есть следующий XML:
<?xml version="1.0" encoding="UTF-8"?>
<persons xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="test.xsd">
<person version="1">
<firstname>toto</firstname>
<lastname>tutu</lastname>
</person>
<person version="2">
<firstname>toto</firstname>
<lastname>tutu</lastname>
<birthdate>2017-12-18</birthdate>
</person>
</persons>
XSD выглядит так:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
elementFormDefault="qualified"
vc:minVersion="1.1">
<xs:complexType name="person_v1">
<xs:sequence>
<xs:element name="firstname" type="xs:token"/>
<xs:element name="lastname" type="xs:token"/>
</xs:sequence>
<xs:attribute name="version" type="xs:token" use="required" fixed="1"/>
</xs:complexType>
<xs:complexType name="person_v2">
<xs:sequence>
<xs:element name="firstname" type="xs:token"/>
<xs:element name="lastname" type="xs:token"/>
<xs:element name="birthdate" type="xs:date"/>
</xs:sequence>
<xs:attribute name="version" type="xs:token" use="required" fixed="2"/>
</xs:complexType>
<xs:element name="person">
<xs:alternative test="@version=1" type="person_v1"/>
<xs:alternative test="@version=2" type="person_v2"/>
</xs:element>
<xs:element name="persons">
<xs:complexType>
<xs:sequence>
<xs:element ref="person" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
XML проверяется на соответствие XSD, но в XSD:
- Если я удаляю атрибут версии, он проверяет,
- Если я заменю версию 1 на 3, она проверяет,
- Если я удаляю все содержимое человека, это подтверждает.
Там должно быть что-то не хватает на моем XSD.
1 ответ
- Если я удаляю атрибут версии, он проверяет,
Как и должно быть, потому что, когда нет xs:alternative
тесты совпадают, person
может быть xs:anyType
в соответствии с общими правилами отображения для объявлений элементов.
- Если я заменю версию 1 на 3, она проверяет,
Как и должно быть по той же причине, что и #1.
- Если я удаляю все содержимое человека, это подтверждает.
Нет, это не так. Возможно, вы действительно не связали XML-документ с вашим XSD, или вы случайно соединили эксперимент № 3 с экспериментами № 1 или № 2.
Обновленный XSD
В следующем обновленном XSD указан тип по умолчанию person
скорее, чем xs:anyType
чтобы избежать сюрпризов № 1 и № 2. Обратите внимание, что он также использует расширение для консолидации общих частей деклараций person_v1
а также person_v2
в person_v
и выполнить требование, чтобы альтернативные типы были получены из общего базового класса. (Если не указано, это xs:anyType
и, как правило, остается незамеченным.)
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
elementFormDefault="qualified"
vc:minVersion="1.1">
<xs:complexType name="person_v">
<xs:sequence>
<xs:element name="firstname" type="xs:token"/>
<xs:element name="lastname" type="xs:token"/>
</xs:sequence>
<xs:attribute name="version" type="xs:token" use="required"/>
</xs:complexType>
<xs:complexType name="person_v1">
<xs:complexContent>
<xs:extension base="person_v"/>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="person_v2">
<xs:complexContent>
<xs:extension base="person_v">
<xs:sequence>
<xs:element name="birthdate" type="xs:date"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="person" type="person_v">
<xs:alternative test="@version=1" type="person_v1"/>
<xs:alternative test="@version=2" type="person_v2"/>
</xs:element>
<xs:element name="persons">
<xs:complexType>
<xs:sequence>
<xs:element ref="person" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Обновление: вот обновление person_v
требовать, чтобы версия была 1
или же 2
для решения проблемы в комментариях:
<xs:complexType name="person_v">
<xs:sequence>
<xs:element name="firstname" type="xs:token"/>
<xs:element name="lastname" type="xs:token"/>
</xs:sequence>
<xs:attribute name="version" use="required">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:minInclusive value="1"/>
<xs:maxInclusive value="2"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>