Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xs:choice and xs:sequence ignored in properties #55

Open
lmichel opened this issue Jan 4, 2017 · 6 comments
Open

xs:choice and xs:sequence ignored in properties #55

lmichel opened this issue Jan 4, 2017 · 6 comments
Assignees

Comments

@lmichel
Copy link

lmichel commented Jan 4, 2017

The following schema element

<xs:complexType name="Resource">
  <xs:annotation><xs:documentation>
     Added in Version 1.2: INFO for diagnostics in several places
  </xs:documentation></xs:annotation>
  <xs:sequence>
    <xs:element name="DESCRIPTION" type="anyTEXT" minOccurs="0"/>
    <xs:element name="INFO" type="Info" minOccurs="0" maxOccurs="unbounded"/>
    <xs:choice minOccurs="0" maxOccurs="unbounded">
      <xs:element name="COOSYS" type="CoordinateSystem"/><!-- Deprecated in V1.2 -->
      <xs:element name="GROUP" type="Group" />
      <xs:element name="PARAM" type="Param" />
    </xs:choice>
</xs:complexType>

gives this JSON schema fragment:

   "Resource": {
      "properties": {
        "name": {
          "type": "string"
        },
        "DESCRIPTION": {
          "$ref": "#/definitions/anyTEXT"
        },
        "INFO": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/Info"
          },
          "minItems": 0
        }
}

We can see that children elements COOSYS/GROUP/PARAM are ignored. Therefore they are not validated although their schema is well defined in the schema.

@fnogatz fnogatz self-assigned this Jan 4, 2017
@fnogatz
Copy link
Owner

fnogatz commented Jan 4, 2017

The xs:choice has not been implemented yet. I am currently thinking about an appropriate JSON Schema translation. It is not trivial 😞 Consider the following small XSD snippet:

<xs:sequence>
  <xs:element name="owl" type="xs:string" />
  <xs:choice>
    <xs:element name="cat" type="xs:string" />
    <xs:element name="dog" type="xs:string" />
    <xs:element name="wolf" type="xs:string" />
  </xs:choice>
</xs:sequence>

A possible direct translation would be:

{
  "type": "object",
  "properties": {
    "owl": {
      "type": "string"
    },
    "cat": {
      "type": "string"
    },
    "dog": {
      "type": "string"
    },
    "wolf": {
      "type": "string"
    }
  },
  "oneOf": [
    {
      "required": [ "cat" ]
    },
    {
      "required": [ "dog" ]
    },
    {
      "required": [ "wolf" ]
    }
  ]
}

But what if we change one of the minOccurs to 0? This is perfectly valid in XML Schema and in some cases even useful:

<xs:sequence>
  <xs:element name="owl" type="xs:string" />
  <xs:choice>
    <xs:element name="cat" type="xs:string" />
    <xs:element name="dog" type="xs:string" minOccurs="0" />
    <xs:element name="wolf" type="xs:string" />
  </xs:choice>
</xs:sequence>

If we change the JSON Schema accordingly, the following is the result:

{
  "type": "object",
  "properties": {
    "owl": {
      "type": "string"
    },
    "cat": {
      "type": "string"
    },
    "dog": {
      "type": "string"
    },
    "wolf": {
      "type": "string"
    }
  },
  "oneOf": [
    {
      "required": [ "cat" ]
    },
    {
      
    },
    {
      "required": [ "wolf" ]
    }
  ]
}

But this is not the same as the given XML Schema! Although the object containing only a owl property will pass the validation, the following does not:

{
  "owl": "a",
  "cat": "b",
}

The same applies for modelling the oneOf with sub-schemas of the form { "properties": { "cat": {} } } instead of { "required": [ "cat" ] }, since the empty schema matches all objects and we can not use "additionalProperties": false in the sub-schemas.

So we have to first think of an appropriate representation of these XML Schemas.

@lmichel
Copy link
Author

lmichel commented Jan 5, 2017

Following my understanding of XML schema, putting minOccurs="0" within a "choice " is an (legal) over-definition since each choice item has an implicit minOccurs="0" allowing it not to be chosen.
My answer for this case would be to support the "choice" element, which is a basic feature of XSD but ignoring minOccurs="0" in this context.

@mozi
Copy link

mozi commented Dec 7, 2017

@fnogatz is there an update on this issue? would appreciate a basic implementation with the first suggestion above.

@SensibleWood
Copy link

+1 for a first pass implementation to this (have wrapped xsd2json in my own xs:choice implementation, but it'd be good to get one from source). Great work btw - this utility propelled me about 4 weeks forward on some work I'm doing

@fnogatz
Copy link
Owner

fnogatz commented Mar 28, 2018

have wrapped xsd2json in my own xs:choice implementation

Is this anywhere available? It might be a good inspiration for native xsd2json support.

@marc1n
Copy link

marc1n commented Feb 5, 2021

<xs:sequence>
  <xs:element name="owl" type="xs:string" />
  <xs:choice>
    <xs:element name="cat" type="xs:string" />
    <xs:element name="dog" type="xs:string" minOccurs="0" />
    <xs:element name="wolf" type="xs:string" />
  </xs:choice>
</xs:sequence>

could be translated to:

type: object
properties:
  owl:
    type: string
required: [owl]
oneOf:
  - properties:
      cat:
        type: string
    required: [cat]
  - properties:
      dog:
        type: string
  - properties:
      wolf:
        type: string
    required: [wolf]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants