问题
I'd like to validate XML "filter" blocks of 2 kinds, whose "shape" contains either of 2 values : "empty" or "circle" :
- if "empty", the block should only contain "shape".
- if "circle", "center" and "diameter" are expected.
XML exemple :
<filter>
<shape>empty</shape>
</filter>
<filter>
<shape>circle</shape>
<center>10.3</center>
<diameter>5.1</diameter>
<filter>
I have tried this XSD schema :
<xs:element name="filter">
<xs:complexType>
<xs:choice>
<xs:all>
<xs:element name="shape" type="xs:string" fixed="circle"/>
<xs:element name="center" type="xs:decimal"/>
<xs:element name="diameter" type="xs:decimal"/>
</xs:all>
<xs:element name="shape" type="xs:string" fixed="empty"/>
</xs:choice>
</xs:complexType>
</xs:element>
Unsuccessfully... xmllint complains :
mytest.xsd:160: element all: Schemas parser error : Element '{http://www.w3.org/2001/XMLSchema}choice': The content is not valid. Expected is (annotation?, (element | group | choice | sequence | any)*).
WXS schema mytest.xsd failed to compile
If I replace xs:all with xs:sequence, it says :
mytest:158: element complexType: Schemas parser error : local complex type: The content model is not determinist.
WXS schema mytest.xsd failed to compile
How to write this piece of XSD - if possible ?
I know that if my XML was using a "shape0" instead of "shape" for "empty" :
<filter>
<shape0>empty</shape0>
</filter>
<filter>
<shape>circle</shape>
<center>10.3</center>
<diameter>5.1</diameter>
<filter>
it would validate fine with :
<xs:element name="filter">
<xs:complexType>
<xs:choice>
<xs:sequence>
<xs:element name="shape" type="xs:string" fixed="circle"/>
<xs:element name="center" type="xs:decimal"/>
<xs:element name="diameter" type="xs:decimal"/>
</xs:sequence>
<xs:element name="shape0" type="xs:string" fixed="empty"/>
</xs:choice>
</xs:complexType>
</xs:element>
But, unfortunately, my XML uses the same keyword...
回答1:
In XSD 1.0, it's not possible to define rules for the structure that depend on the content.
In XSD 1.1 you can do this with assertions, e.g. <xs:assert test="not(shape='empty' and (centre or diameter))"/>
来源:https://stackoverflow.com/questions/59317973/how-to-use-choice-from-complex-types-in-xsd-with-2-values-of-a-same-element