【问题标题】:Can I validate that nodes exist that edges in a graph point to with JSON SCHEMA?我可以使用 JSON SCHEMA 验证图中边指向的节点是否存在吗?
【发布时间】:2022-12-01 08:09:49
【问题描述】:

我想用 JSON Schema 描述顶点和边的网络图。

示例 JSON 可能如下所示:

"V":["1","2","3"],
"E":[{
    "v1":"1",
    "v2":"2"
  },{
    "v1":"2",
    "v2":"3"
  }

我有一组 3 个顶点和 2 个边来连接它们。我希望所有顶点都有一个任意的字符串标识符,所以它也可以是“node1”或“panda”。但是,有没有办法验证我的边的端点是否仅指向现有顶点?

即:不应通过:

"V":["n1","n2","n3"],
"E":[{
    "v1":"n1",
    "v2":"IdThatDoesNotExistAbove"
  }

我查看了 ENUM,但是,我很难让它们指向我想要验证的 JSON 中的数据,而不是指向规范本身。

【问题讨论】:

标签: json jsonschema json-schema-validator python-jsonschema


【解决方案1】:

使用jq可以解决这个任务。

jq -r '([.E[] | to_entries[].value] | unique) - .V |
       if length == 0
       then "all vertices defined"
       else "undefined vertices: (.)
" | halt_error(1)
       end
' "$FILE"
echo "exit code: $?"

输出有效文件

all vertices defined
exit code: 0

输出无效文件

undefined vertices: ["IdThatDoesNotExistAbove"]
exit code: 1

如果您对哪些顶点未定义不感兴趣,您可以使用较短的版本

jq -e '([.E[] | to_entries[].value]) - .V | length == 0' "$FILE"
echo "exit code: $?"

输出有效文件

true
exit code: 0

输出无效文件

false
exit code: 1

【讨论】:

    【解决方案2】:

    JSON Schema 没有像这样定义引用数据的方法,但它确实有扩展词汇表,允许定义自定义关键字。我创建了一个 data vocabulary 来精确地完成您想要做的事情。

    {
        "$schema": "https://json-everything.net/meta/data-2022",
        "type": "object",
        "$defs": {
            "user-defined-vertex": {
                "data": {
                    "enum": "/V"
                }
            }
        },
        "properties": {
            "V": {
                "type": "array",
                "items": {"type": "string"}
            },
            "E": {
                "type": "array",
                "items": {
                    "type": "object",
                    "properties":{
                        "v1": { "$ref": "#/$defs/user-defined-vertex" },
                        "v2": { "$ref": "#/$defs/user-defined-vertex" }
                    },
                    "required": ["v1", "v2"],
                    "additionalProperties": false
                }
            }
        },
        "additionalProperties": false
    }
    

    其中的关键部分是#/$defs中的data关键字。

    data 将带有模式关键字的对象作为键,将 JSON 指针或 URI 作为值。如果您想从实例数据中提取值,您将使用 JSON 指针。对于其他情况,您将使用 URI。

    所以对于这种情况,我有

    {
        "data": {
            "enum": "/V"
        }
    }
    

    它表示从实例数据中的/V 中获取值并将其用作enum 关键字的值。

    #/properties/V 中,您定义 /V 必须是一个包含字符串值的数组。


    然而,据我所知,这个词汇表只适用于我的库,JsonSchema.Net,你需要扩展包JsonSchema.Net.Data

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多