65

I want to have a JSON Schema with unknown property names in an array of objects. A good example is the meta-data of a web page:

      "meta": {
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "unknown-attribute-1": {
              "type": "string"
            },
            "unknown-attribute-2": {
              "type": "string"
            },
            ...
          }
        }
      }

Any ideas please, or other way to reach the same?

Thami Bouchnafa
  • 1,987
  • 1
  • 15
  • 21
  • Please provide more details on what you want to achieve – Christophe Aug 17 '15 at 09:07
  • The meta-data is an array of object, where I don't know the possible names of the attributes of the objects – Thami Bouchnafa Aug 17 '15 at 10:59
  • Which constraints do you want to enforce to your unnamed properties? Do you want them to have some type, or do you want their names to follow some pattern? You can have unknown property names in JSON schema provided you do not have additionalProperties=false – jruizaranguren Aug 17 '15 at 11:34
  • yes, I want to enforce them to be of type "string" The names do not have to match any pattern – Thami Bouchnafa Aug 17 '15 at 11:37
  • Have a look [at this answer](https://stackoverflow.com/a/26848488/5663986) for a much much simpler way of achieving this compared to what suggested below. – belvederef May 07 '20 at 11:26

3 Answers3

129

Use patternProperties instead of properties. In the example below, the pattern match regex .* accepts any property name and I am allowing types of string or null only by using "additionalProperties": false.

  "patternProperties": {
    "^.*$": {
      "anyOf": [
        {"type": "string"},
        {"type": "null"}
      ]
    }
  },
  "additionalProperties": false

... or if you just want to allow a string in your "object" (like in the original question):

  "patternProperties": {
    "^.*$": {
        {"type": "string"},
    }
  },
  "additionalProperties": false
Jean-Francois T.
  • 11,549
  • 7
  • 68
  • 107
pink spikyhairman
  • 2,391
  • 1
  • 16
  • 13
17

You can make constraints on properties not explicitly defined. The following schema enforces "meta" to be an array of objects whose properties are of type string:

{
    "properties" : {
        "meta" : {
            "type" : "array",
            "items" : {
                "type" : "object",
                "additionalProperties" : {
                    "type" : "string"
                }
            }
        }
    }
}

In case you just want to have an array of strings, you may use the following schema:

{
    "properties" : {
        "meta" : {
            "type" : "array",
            "items" : {
                "type" : "string"
            }
        }
    }
}
jruizaranguren
  • 12,679
  • 7
  • 55
  • 73
1

The Solution of @jruizaranguren works for me. Though I am the same who defines the schema, i choosed another solution

"meta": {
        "type": "array",
        "items": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "value": {
                "type": "string"
              }
            }
          }
        }
      }

I converted the object to an array of name-value objects An example of a valid JSON:

"meta": [
    [
      {
        "name": "http-equiv",
        "value": "Content-Type"
      },
      {
        "name": "content",
        "value": "text/html; charset=UTF-8"
      }
    ],
    [
      {
        "name": "name",
        "value": "author"
      },
      {
        "name": "content",
        "value": "Astrid Florence Cassing"
      }
    ]
  ]
Thami Bouchnafa
  • 1,987
  • 1
  • 15
  • 21