Restrict possible values of a field to the keys of certain map in JSON schema [duplicate]

I'd like to use JSON schema to validate some values. I two objects, call them trackedItems and trackedItemGroups. The trackedItemGroups are a group name and a list of trackedItems names. For example, the schema is similar to:

"TrackedItems": {
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "TrackedItemName": { "type": "string" },
      "Properties": {  ----  }
    }
  }
},
"TrackedItemGroups": {
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "GroupName": {
         "type": "string"
      },
     "TrackedItems": {
        "type": "array",
        "items": {"type": "string"}
      }
    }
  }
}

I'd like to validate that every string in a TrackedItemGroups's TrackedItems array is a name that's been defined in TrackedItems.TrackedItemName.

This would be something like using the enum property to restrict the values, but the enum list is generated based on the values in TrackedITems.TrackedItemName.

How can I write the schema to use the JSON's own data for validation?

I'm aware I could move things around, i.e. the TrackedItems define the group they're in, but there are hundreds of tracked items and this organization works much better for my use case.

I've tried this:

"TrackedItems": {
   "type": "array",
    "items": {
       "oneOf": [
            {"$ref":"#/properties/TrackedItems/items/properties/TrackedItemName"}
        ]
     }
 }

But this results in an error:

Newtonsoft.Json.Schema.JSchemaReaderException: Could not resolve schema reference '#/properties/TrackedItems/items/properties/TrackedItemName'.

For a data example, if I had the TrackedItems:

Item1, Item2, ItemA, ItemB, ItemC

And groups:

Group1: Item1, ItemB, ItemC

Group2: Item1, Item2, ItemZ

Group2 would throw a violation because it contains an item not defined in TrackedItems.


Solution 1:

Being a vocabulary for validation (and certain other things described by trivial assertions), JSON Schema does not provide a way to verify the consistency of data.

Validation means assertions like "Verify that X is a string."

Consistency means things like "Verify that X is the ID of an existing, active user."

Since data being compared might be in another database altogether, and since these sorts of assertions are non-trivial, JSON Schema leaves verifying the consistency of data up to the application and/or other technologies. Some implementations have vendor-specific extensions for intra-document comparisons, however these are not standardized, and I'm not aware of any that would work here.


A $ref reference doesn't work here, as it's just a way to substitute in another schema by reference. If you can manage to get the reference to work (and I'm not sure why you got an error, this is implementation-specific detail), this schema:

{ "oneOf": [
    {"$ref":"#/properties/TrackedItems/items/properties/TrackedItemName"}
] }

Is the exact same thing as saying:

{ "oneOf": [
    {"type": "string"}
] }

Since you're asking "verify that one of the following one statements is true", this is also the same as simply:

{"type": "string"}

This is not to say you can't declare relationships between data in JSON using JSON Schema, but JSON Schema is somewhat opinionated about using URIs and hyperlinks to do so.