问题
XSD1.1 allows the type of an element to depend on one of its attributes. For example,
<integer kind='s'>100</integer>
will cause the type of 'element' to be xs:short. Here is what I have got:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
elementFormDefault="qualified"
attributeFormDefault="unqualified"
vc:minVersion="1.1">
<xs:complexType name="GenericInt">
<xs:simpleContent>
<xs:extension base="xs:integer">
<xs:attribute name="kind" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name="integer" type="GenericInt">
<xs:alternative test="@kind='b'" type="xs:byte"/>
<xs:alternative test="@kind='s'" type="xs:short"/>
<xs:alternative test="@kind='i'" type="xs:int"/>
<xs:alternative test="@kind='l'" type="xs:long"/>
<xs:alternative type="GenericInt"/>
</xs:element>
</xs:schema>
When I tried to save the file in Altova XMLSpy, an error occurred: cos-st-derived-ok.2: Simple type definition 'xs:byte' is not validly derived from 'GenericInt'.
So how should I correct the XSD code?
回答1:
An alternative approach would be something like
<xs:complexType name="GenericInt">
<xs:simpleContent>
<xs:extension base="xs:integer">
<xs:attribute name="kind" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
<xs:assert test="(@kind='b' and $value = (-128 to 127))
or (@kind='s' and $value = (-32768 to 32767))
or (....)"/>
</xs:complexType>
though you wouldn't get the precise PSVI type annotation that way.
回答2:
Well, I got it working like this:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
elementFormDefault="qualified"
attributeFormDefault="unqualified"
vc:minVersion="1.1">
<xs:complexType name="bInt">
<xs:simpleContent>
<xs:extension base="xs:byte">
<xs:attribute name="kind" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="sInt">
<xs:simpleContent>
<xs:extension base="xs:short">
<xs:attribute name="kind" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="iInt">
<xs:simpleContent>
<xs:extension base="xs:int">
<xs:attribute name="kind" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="lInt">
<xs:simpleContent>
<xs:extension base="xs:long">
<xs:attribute name="kind" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="gInt">
<xs:simpleContent>
<xs:extension base="xs:integer">
<xs:attribute name="kind" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name="integer">
<xs:alternative test="@kind='b'" type="bInt"/>
<xs:alternative test="@kind='s'" type="sInt"/>
<xs:alternative test="@kind='i'" type="iInt"/>
<xs:alternative test="@kind='l'" type="lInt"/>
<xs:alternative type="gInt"/>
</xs:element>
</xs:schema>
Any better solution?
来源:https://stackoverflow.com/questions/26094862/how-to-use-conditional-type-assignment-for-different-integer-types-in-xsd