Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Represent xs:choice as JSON schema

Wrapping my head around JSON Schema's oneOf.

I want to produce a JSON version of an XML format and have a JSON schema validate the essential aspects (I know there'll be some differences).

I have an XML Schema concept where you can specify a name or ID for some entity:

<xs:element name="Entity" type="test:EntityType" />
    <xs:complexType name="EntityType">
        <xs:choice>
            <xs:element name="EntityID" />
            <xs:element name="EntityName" />
        </xs:choice>
    </xs:complexType>

In the corresponding JSON schema I'm having trouble with where to put the oneOf object.

In the JSON schema examples it looks like you should put complete schemas into oneOf, is that right? How should this look in the general case? Has anyone documented the similarities and differences between XSD and JSON schema for reference?

like image 405
Michael Avatar asked Jan 28 '26 04:01

Michael


2 Answers

I didn't try it myself, but I think you need something like this:

{
    "allOf" : [
        {
            "type" : "object",
            "properties" : {
                "entityName" : {"type" : "string"},
                "entityID" : {"type" : "integer"}
            }
        },
        {
            "oneOf" : [
                {
                    "required" : ["entityName"]
                },
                {
                    "required" : ["entityID"]
                }
            ]
        }
    ]
}

So after under a top-level "allOf" you first describe the basic structure, then with a "oneOf" you express the choice.

like image 170
erosb Avatar answered Jan 30 '26 08:01

erosb


I think that the issue you are facing is a small impedance mismatch between the XML and JSON data models.

While both are based on trees, the labels of the XML elements or JSON keys are not placed on the same places in the trees: from a logical perspective, XML element names are placed on the nodes of the tree, while JSON keys are placed on the edges of the tree.

This becomes apparant in XML Schema and in JSON Schema, especially with your example. XML schema, with xs:choice, provides a choice between possible elements (nodes in the XML information set data model), and since these elements carry their names with them (labels on nodes), you get to choose these element names as well together with their layouts.

However, in JSON Schema, the oneOf construct allows to pick an object layout, but this does not include picking a name (labels on edges). In other words, the key (EntityID or EntityName) is specified outside of the oneOf construct. This means that the mapping of xs:choice to oneOf is not as straightforward as it seems and it requires finding less obvious workarounds.

like image 33
Ghislain Fourny Avatar answered Jan 30 '26 07:01

Ghislain Fourny