【问题标题】:json-schema: how to transform from one json-schema to anotherjson-schema:如何从一种 json-schema 转换为另一种
【发布时间】:2016-07-20 14:10:18
【问题描述】:

我有两个不同的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" }
    }
}

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

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

validates(calendarA, schemaA); // true

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

var calendarB = fromSchemaAtoB(calendarA, schemaA, schemaB);
validates(calendarB, schemaB); // true

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

schemaB.properties.foo = schemaA.properties.dtstart

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

非常感谢您!

JG

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

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

var calendarB = transform(calendarA, schemaA, schemaB, relationsAtoB);
validates(calendarB, schemaB); // true

接下来的问题是如何更好地描述“relationsAtoB”以及如何实现“transform”功能。

【问题讨论】:

  • 嗨,请告诉我你更喜欢什么,在创建对象之前转换方案数据或将现有对象变异为另一个?
  • var calendarB = fromSchemaAtoB(calendarA, schemaA, schemaB); 如果您确实确定要将shemeA 转换为schemeB 而不是改变ObjectA,则需要一个模板而不是schemeB,该模板将描述schemeA 中的属性关系到schemeB 中的专用属性。如果您不喜欢创建模板,fromSchemaAtoB() 应该在没有模板的情况下进行所有转换(但这是非常不支持的方法,最好更改 CONFIG 而不是方法本身)
  • 嗨。如果“在创建对象之前转换方案数据”是指第二个对象是一个全新的对象,我会说我更喜欢这个选项。您的第二个选项也非常有趣,特别是对于出于性能原因我想要变异的大型对象。我想理想的框架应该针对两种转换类型,一种是创建全新对象的默认类型,另一种是对输入对象进行变异的第二种类型。但是现在新的对象。谢谢@Appeiron
  • 上一个答案是针对您的第一条评论。对于第二条评论,为了澄清,模式不应该发生变化。它们在转换之前和之后应该是相同的。
  • 为了便于转换,最好有模板,您将使用传入的数据进行装饰,并依赖于您传递的关于您在两个方案之间的关系的配置:jsfiddle.net/unLjLtey/2 这取决于您如何处理其他方案没有在关系中定义的属性,应该让转换器复制它们或不触碰就离开。

标签: javascript templates jsonschema json-ld


【解决方案1】:

我相信像this 这样的库可以用来解决您的问题。 这并没有直接解决这个问题(从一个 JSON 模式转换到另一个),但你可以做的(这是我目前正在做的)如下:

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

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

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

另外,请记住,您不能拥有12 并以某种方式自动生成3。这是因为有不止一个映射函数会获取遵循架构 1 的数据并生成遵循架构 2 的数据。

【讨论】:

    【解决方案2】:

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

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

    jsonA

    {
      "key1": "value1",
      "key2": "value2"
    }
    

    架构A

    {
      "type": "object",
      "additionalProperties": {
        "type": "string"
      }
    }
    

    架构B

    {
      "type": "array",
      "items": {
        "type": "array",
        "items": [
          { "type": "string" },
          { "type": "string" }
        ]
      }
    }
    

    您能仅从这些信息中找出应该进行的转换吗?也许吧,但是有太多的歧义,无法解决问题。此转换将对象转换为键/值对数组。

    jsonB

    [
      ["key1", "value1"],
      ["key2", "value2"]
    ]
    

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

    JSON-LD

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

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

    【讨论】:

    • 谢谢@jason,刚刚在问题中添加了更多信息,以澄清当然必须提供模式之间的关系。 JSON-LD 似乎很有趣。您能否提供一个示例,说明如何使用框架方法使用 JSON-LD 执行此操作?谢谢。
    • 您好,您找到解决方案了吗,您最终采用了哪种方法?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-27
    • 2020-12-26
    • 2021-09-16
    相关资源
    最近更新 更多