json-schema:如何从一个 json-schema 转换到另一个

use*_*015 8 javascript templates jsonschema json-ld

我有两种不同的json-schemas

schemaA -> 在http://json-schema.org/calendar定义的日历

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "description": "A representation of an event",
    "type": "object",
    "required": [ "dtstart", "summary" ],
    "properties": {
        "dtstart": {
            "format": "date-time",
            "type": "string",
            "description": "Event starting time"
        },
        "dtend": {
            "format": "date-time",
            "type": "string",
            "description": "Event ending time"
        },
        "summary": { "type": "string" },
        "location": { "type": "string" },
        "url": { "type": "string", "format": "uri" },
        "duration": {
            "format": "time",
            "type": "string",
            "description": "Event duration"
        },
        "rdate": {
            "format": "date-time",
            "type": "string",
            "description": "Recurrence date"
        },
        "rrule": {
            "type": "string",
            "description": "Recurrence rule"
        },
        "category": { "type": "string" },
        "description": { "type": "string" },
        "geo": { "$ref": "http: //json-schema.org/geo" }
    }
}
Run Code Online (Sandbox Code Playgroud)

schemaB -> 另一个日历模式(也是 json-schema 版本draft-04)

我的问题很简单。我有一个遵循第一个模式的 javascript 对象“calendarA”,即,

validates(calendarA, schemaA); // true
Run Code Online (Sandbox Code Playgroud)

我想描述模式之间的转换,即从模式A 到模式B,因此我可以将日历A 作为输入传递并获得适合模式B 的新日历B。把它放在代码中:

var calendarB = fromSchemaAtoB(calendarA, schemaA, schemaB);
validates(calendarB, schemaB); // true
Run Code Online (Sandbox Code Playgroud)

从您的角度来看,最好的方法/工具是从 SchemaAtoB 人那里编写的?我真的很想使用模式来描述转换,例如:

schemaB.properties.foo = schemaA.properties.dtstart
Run Code Online (Sandbox Code Playgroud)

我看到了很多基本的 json 转换包,但在我看来,在大多数情况下,您将输出指定为不考虑模式的外部模板(因此结果对于 schemaB 可能无效)。

非常感谢您提前!

JG

PS:如果可能的话,我更喜欢基于 javascript 的解决方案,但我真的愿意接受任何可能性。

编辑 1:为了在阅读@jason 的回答后澄清,问题是如何更好地描述模式之间的这种关系以及如何应用它们来获得日历 B。因此,如果您更喜欢:

var calendarB = transform(calendarA, schemaA, schemaB, relationsAtoB);
validates(calendarB, schemaB); // true
Run Code Online (Sandbox Code Playgroud)

然后问题是如何更好地描述“relationsAtoB”以及如何实现“转换”功能。

Geo*_*rge 7

我相信这样的图书馆可以用来解决您的问题。这并不能直接解决问题(从一种 JSON 模式转换为另一种模式),但您可以执行以下操作(这就是我目前正在做的事情):

  1. 为您的输入指定 JSON 架构
  2. 为您的输出指定 JSON 架构
  3. 指定一个映射模板(例如使用我引用的库)。

当然,理想情况下你不必两者都做23但我还没有找到自动执行此操作的东西。因此,例如,您可以指定映射模板并创建一些库函数,该函数将其以及 JSON 模式作为1输入,并生成 JSON 模式作为3其输出。

然而,这并不是微不足道的,所以目前我指定了23

另外,请记住,您不能拥有12并以某种方式自动生成3. 这是因为有多个映射函数可以获取符合 schema 的数据1并生成符合 schema 的数据2


Jas*_*ers 3

这不是 JSON Schema 的设计目的。将 JSON 从一种 JSON 模式转换为另一种模式需要人工提供转换的上下文。

例如,这是人类要做的相当简单的转换。

jsonA

{
  "key1": "value1",
  "key2": "value2"
}
Run Code Online (Sandbox Code Playgroud)

模式A

{
  "type": "object",
  "additionalProperties": {
    "type": "string"
  }
}
Run Code Online (Sandbox Code Playgroud)

方案B

{
  "type": "array",
  "items": {
    "type": "array",
    "items": [
      { "type": "string" },
      { "type": "string" }
    ]
  }
}
Run Code Online (Sandbox Code Playgroud)

你能仅从这些信息中找出应该进行什么样的转换吗?也许吧,但是有太多的歧义,不可能有问题地完成。此转换将对象转换为键/值对数组。

jsonB

[
  ["key1", "value1"],
  ["key2", "value2"]
]
Run Code Online (Sandbox Code Playgroud)

由于比较方案的模糊性,几乎任何转换都必须根据具体情况手动完成。我认为这种方法不会走得太远。

JSON-LD

您可能需要考虑JSON-LD作为替代方案。JSON-LD 文档将数据描述为有向图。因此,可以通过多种方式将 JSON-LD 文档表示为 JSON 对象。在 JSON-LD 中,这称为成帧

这个想法是将您的日历描述为 JSON-LD 文档,可以将其构建为匹配 schemaA 或 schemaB。换句话说,JSON-LD 文档是消除模式之间的歧义所需的上下文。我会举一个例子,但我不太了解 JSON-LD。如果您认为它可以解决您的问题,我会将其留给您进行研究。