How to use <choice> from complex types in XSD with 2 values of a same element?

六月ゝ 毕业季﹏ 提交于 2020-01-25 07:29:23

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!