Search code examples
liquid-xml

Not required fields were set to be required after converting xsd to json schema from Liquid Studio


Xsd elements with attribute "minOccur" setted to be 0 which is suppose to be a not required field, were set to be required after converting from xsd to json schema.

Here is the case:

XSD:

<?xml version="1.0" encoding="utf-8" ?>
<!--Created with Liquid Studio (https://www.liquid-technologies.com)-->
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element id="T01" name="Test">
        <xs:complexType>
            <xs:sequence>
                <xs:element id="T02" name="Form" maxOccurs="40">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element id="T03" name="Numbers" minOccurs="0" maxOccurs="500">
                                <xs:complexType>
                                    <xs:sequence>
                                        <xs:element id="N01" name="Attr1" minOccurs="0" />
                                        <xs:element id="N02" name="Attr2" minOccurs="0" />
                                        <xs:element id="N03" name="Attr3" minOccurs="0">
                                            <xs:simpleType>
                                                <xs:restriction base="xs:string">
                                                    <xs:minLength value="1" />
                                                </xs:restriction>
                                            </xs:simpleType>
                                        </xs:element>
                                    </xs:sequence>
                                </xs:complexType>
                            </xs:element>
                            <xs:element id="T04" name="List">
                                <xs:complexType>
                                    <xs:sequence>
                                        <xs:element name="Attr1" id="L01"/>
                                        <xs:element name="Attr2" id="L02"/>
                                        <xs:element name="Attr3" id="L03" minOccurs="0" maxOccurs="2"/>
                                    </xs:sequence>
                                </xs:complexType>
                            </xs:element>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

Output JSON Schema from Liquid Studio:

{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "type": "object",
    "properties": {
        "Test": {
            "$ref": "#/$defs/Test"
        }
    },
    "additionalProperties": false,
    "required": [
        "Test"
    ],
    "$defs": {
        "Test": {
            "type": "object",
            "properties": {
                "Form": {
                    "type": "array",
                    "maxItems": 40,
                    "minItems": 1,
                    "items": {
                        "type": "object",
                        "properties": {
                            "Numbers": {
                                "type": "array",
                                "maxItems": 500,
                                "items": {
                                    "type": "object",
                                    "properties": {
                                        "Attr1": {
                                            "type": "object",
                                            "additionalProperties": false
                                        },
                                        "Attr2": {
                                            "type": "object",
                                            "additionalProperties": false
                                        },
                                        "Attr3": {
                                            "type": "string",
                                            "minLength": 1
                                        }
                                    },
                                    "additionalProperties": false
                                }
                            },
                            "List": {
                                "type": "object",
                                "properties": {
                                    "Attr1": {
                                        "type": "object",
                                        "additionalProperties": false
                                    },
                                    "Attr2": {
                                        "type": "object",
                                        "additionalProperties": false
                                    },
                                    "Attr3": {
                                        "type": "array",
                                        "maxItems": 2,
                                        "items": {
                                            "type": "object",
                                            "additionalProperties": false
                                        }
                                    }
                                },
                                "additionalProperties": false,
                                "required": [
                                    "Attr1",
                                    "Attr2",
                                    "Attr3"
                                ]
                            }
                        },
                        "additionalProperties": false,
                        "required": [
                            "Numbers",
                            "List"
                        ]
                    }
                }
            },
            "additionalProperties": false,
            "required": [
                "Form"
            ]
        }
    }
}

Elements Test.Numbers and Test.List.Attr3 should not be required as their "minOccurs" = 0 but the output json schema shows that they are required.


Solution

  • If you have an XSD schema that looks like this

    <xs:element name="Thing" minOccurs="0" maxOccurs="2"/>
    

    It will validate XML data that looks like this

    <Parent>
        <Thing>1</Thing>
        <Thing>2</Thing>
    </Parent>
    

    The equivalent JSON document would look like this

    { "Thing" : [1, 2] }
    

    However if the XML data does not contain any Things i.e.

    <Parent></Parent>
    

    The equivalent JSON could look like this

    { "Thing" : [] }        
    

    or like this

    { }
    

    Both are valid, both convey a subtilty different meaning that is not present in the source XML structure. Currently we do the conversion by forcing the Thing property to be required, and it contains an empty array if there are no items.

    Taking this into account we will add an option making it possible to select whether to treat arrays as required properties in the JSON schema.

    I will update the thread when the update is available.

    UPDATE 16th October 2024: Liquid Studio v20.7.17 is now available and the conversion now works as expected. There is also an option to 'Treat optional arrays as require'.