我可以验证节点的存在,在一个图的边缘指向JSON SCHEMA?



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

JSON示例如下:

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

我有一组3个顶点和2条边来连接它们。我希望所有顶点都有一个任意的字符串标识符,也可以是"node1"或";panda"。然而,有没有一种方法来验证我的边的端点只指向现有的顶点?

。: Should NOT pass:

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

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

使用jq可以解决此任务。

jq -r '([.E[] | to_entries[].value] | unique) - .V |
if length == 0
then "all vertices defined"
else "undefined vertices: (.)n" | 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

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

{
"$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。

相关内容

最新更新