将 JSON 值限制为其他 JSON 对象的名称

Restrict JSON values to the names of other JSON objects

我想使用 JSON 架构来验证某些值。我有两个对象,称它们为 trackedItems 和 trackedItemGroups。 trackedItemGroups 是组名称和 trackedItems 名称列表。例如,架构类似于:

"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"}
      }
    }
  }
}

我想验证 TrackedItemGroupsTrackedItems 数组中的每个字符串都是在 TrackedItems.TrackedItemName 中定义的名称。

这类似于使用 enum 属性 来限制值,但是 enum 列表是根据 TrackedITems.TrackedItemName 中的值生成的。

如何编写架构以使用 JSON 自己的数据进行验证?

我知道我可以四处移动,即 TrackedItems 定义它们所在的组,但有数百个跟踪项目,这个组织更适合我的用例。

我试过这个:

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

但这会导致错误:

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

对于数据示例,如果我有 TrackedItems:

项目 1、项目 2、项目 A、项目 B、项目 C

和群组:

第 1 组: 项目 1、项目 B、项目 C

第 2 组: 项目 1、项目 2、项目 Z

Group2 会引发违规,因为它包含未在 TrackedItems 中定义的项目。

作为 validation 的词汇表(以及由琐碎的断言描述的某些其他事物),JSON Schema 不提供验证 数据的一致性

验证意味着像 "Verify that X is a string."

这样的断言

一致性意味着 "Verify that X is the ID of an existing, active user."

由于被比较的数据可能完全在另一个数据库中,并且由于这些类型的断言很重要,JSON 架构将验证数据的一致性留给应用程序 and/or 其他技术.一些实现具有用于文档内比较的特定于供应商的扩展,但是这些都不是标准化的,我不知道有什么可以在这里工作。


$ref 引用在这里不起作用,因为它只是一种通过引用替换另一个模式的方法。如果您可以设法使引用起作用(我不确定为什么会出现错误,这是特定于实现的细节),则此架构:

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

与说的完全一样:

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

既然你问的是"verify that one of the following one statements is true",这也等同于:

{"type": "string"}

这并不是说您不能使用 JSON Schema 在 JSON 中声明数据之间的关系,但是 JSON Schema 对于使用 URI 和超链接来这样做有些自以为是.