Я хочу написать XML-схему (xsd 1.1) для документа, содержащего параметры. У каждой опции есть имя и тип (например, логическое значение, целое число, строка и т. д.) и данные, соответствующие этому типу. Список типов фиксированный, но довольно длинный. (Только 3 перечислены в листинге 3 для простоты.)
Как мне сделать это без нелепого количества повторений?
Вариант использования 1
Вот действительный документ для этой схемы.
Листинг 1:
<abc:options>
<abc:option name="is-enabled" type="boolean">false</abc:option>
<abc:option name="wing-span" type="float">1.2</abc:option>
</abc:options>
Вариант использования 2
Этот документ недействителен для этой схемы, поскольку бит простого типа неверен для атрибута @type.
<abc:options>
<abc:option name="is-enabled" type="boolean">24</abc:option>
<abc:option name="wing-span" type="float">this-is-not-a-number!</abc:option>
</abc:options>
То, что я пробовал до сих пор ...
Листинг 3 — моя попытка на данный момент. Но это плохо, потому что мне приходится повторно объявлять атрибут @name для каждого типа данных. Есть ли лучшее решение? Другими словами, мне не нужно повторно объявлять атрибут @name для каждого возможного типа данных.
Листинг 3:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:abc="http://www.example.com"
targetNamespace="http://www.example.com"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xs:element name="options">
<xs:complexType>
<xs:sequence minOccurs="1" maxOccurs="unbounded">
<xs:element name="abc:option" type="option-Type"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:simpleType name="option-Datum-Type">
<xs:restriction base="xs:string">
<xs:enumeration value="boolean"/>
<xs:enumeration value="integer"/>
<xs:enumeration value="float"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="option-Type-boolean">
<xs:simpleContent>
<xs:extension base="xs:boolean">
<xs:attribute name="name" type="xs:token" use="required" />
<xs:attribute name="type" type="abc:option-Datum-Type" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="option-Type-string">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="name" type="xs:token" use="required" />
<xs:attribute name="type" type="abc:option-Datum-Type" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="option-Type-float">
<xs:simpleContent>
<xs:extension base="xs:double">
<xs:attribute name="name" type="xs:token" use="required" />
<xs:attribute name="type" type="abc:option-Datum-Type" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="option-Type">
<xs:alternative test="@type='boolean'" type="abc:option-Type-boolean"/>
<xs:alternative test="@type='string'" type="abc:option-Type-string" />
<xs:alternative test="@type='float'" type="abc:option-Type-float" />
<xs:alternative type="xs:error"/>
</xs:complexType>
</xs:schema>
option
тем, что у вас сейчас есть вoption/@name
, а затем использовать, а не изобретать заново,xsi:type
, например это. Дайте мне знать, если вы заинтересованы в том, чтобы этот подход применялся в ответе здесь. - person kjhughes   schedule 12.11.2015