andrewbober / xsd2jsonschema

A pure JavaScript library for translating complex XML Schemas into JSON Schemas.
https://www.xsd2jsonschema.org
Apache License 2.0
47 stars 25 forks source link

Weird handling of array in XSD #11

Open ghilainm opened 5 years ago

ghilainm commented 5 years ago

Seems like arrays defined in XSD generate weird content. Input

 <xs:element name="SomeField" minOccurs="0" maxOccurs="9" type="SomeType">
 </xs:element>

Output

        SomeField:
          oneOf:
            - $ref: '#definitions/SomeType'
            - type: array
              maxItems: 9
              items:
                $ref: '#definitions/SomeType'

For me it should not use oneOf for arrays. I should only be the second entry of the oneOf without oneOf.

ghilainm commented 5 years ago

Seems like you are right, this should be like you defined it. Sorry for opening the issue :). Just didn't get the XSD syntax!

ghilainm commented 5 years ago

I would like to reopen this because what is generated is not really convenient for the Java generator from OpenAPI. Wouldn't it be simpler to generate only this:

        SomeField:
            - type: array
              maxItems: 9
              items:
                $ref: '#definitions/SomeType'
andrewbober commented 5 years ago

Thanks again for the feedback. I will make this an option because the repeating lists in XML Schema don't have to be put into their own aggregate.

Additionally, I've found xml to Json instance converters aren't able to determine that a single element was actually a list of one from a repeating list. Honestly, I don't know how they would tell the difference between a single element of a repeating list vs just a single element without having access to the xml schema.

ghilainm commented 5 years ago

@andrewbober They can't know but as far as I understand we have here the XSD schema, therefore we know it is a list, so I would always use the list synthax in the json, not the single element stuff. That removes the ambiguity. Don't you agree?

andrewbober commented 5 years ago

Honestly, you're not the first one to bring this up so it needs to be addressed. Personally, I like flexibly provided by the anyOf solution but any source code generated from resulting JSON Schema has to accommodate the same flexibility. And it may or may not be of value or applicable to individual schema authors so I think it's best to be an option. If the default functionality is to directly generate a list would that address your concern?

I appreciate all your feedback. It's great to hear from someone trying to use the library.

ghilainm commented 5 years ago

If it is the default it is simpler for me but I can accommodate from an option too :).

I think it is better to not introduce allOf/oneOf by default if possible because some tools (like mine) don't handle it properly by default. I had to post process your output to solve the issue :).

Nice to have somebody taking the time to maintain such a library ;).

bora-fsd commented 3 years ago

Hello @andrewbober, is there a way of disabling anyOf in the output, maybe with some options? I think my problem is related, I have this input:

    <xs:complexType name="StatusReason6Choice__1">
        <xs:annotation>
            <xs:documentation source="Name" xml:lang="EN">StatusReason6Choice__1</xs:documentation>
            <xs:documentation source="Definition" xml:lang="EN">Specifies the reason for the status of the transaction.</xs:documentation>
        </xs:annotation>
        <xs:sequence>
            <xs:choice>
                <xs:element name="Code" type="ExternalStatusReason1Code">
                    <xs:annotation>
                        <xs:documentation source="Name" xml:lang="EN">Code</xs:documentation>
                        <xs:documentation source="Definition" xml:lang="EN">Reason for the status, as published in an external reason code list.</xs:documentation>
                    </xs:annotation>
                </xs:element>
            </xs:choice>
        </xs:sequence>
    </xs:complexType>

Output:

"status_reason6choice_1": {
      "description": "Specifies the reason for the status of the transaction.",
      "type": "object",
      "anyOf": [
        {
          "required": [
            "code"
          ],
          "properties": {
            "code": {
              "$ref": "#/definitions/external_status_reason1code",
              "description": "Reason for the status, as published in an external reason code list."
            }
          }
        }
      ]
    },

which I want to replace with:

"status_reason6choice_1": {
      "description": "Specifies the reason for the status of the transaction.",
      "type": "object",
      "properties": {
            "code": {
              "$ref": "#/definitions/external_status_reason1code",
              "description": "Reason for the status, as published in an external reason code list."
            }
          }
    },

Any ideas how to avoid the anyOf in output?