简体   繁体   English

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

[英]json-schema: how to transform from one json-schema to another

I have the two different json-schemas : 我有两个不同的json-schemas

schemaA -> A calendar as defined at http://json-schema.org/calendar 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 -> Another calendar schema (also json-schema version draft-04) schemaB - >另一个日历模式(也是json-schema版本draft-04)

My quesiton is simple. 我的问题很简单。 I have a javascript object 'calendarA' that follows the first schema, ie, 我有一个跟随第一个模式的javascript对象'calendarA',即

validates(calendarA, schemaA); // true

I want to describe a transformation between the schemas, ie, from schemaA to schemaB, so I can pass calendarA as input and get a new calendarB that fits schemaB. 我想描述模式之间的转换,即从schemaA到schemaB,因此我可以将calendarA作为输入传递并获得适合schemaB的新calendarB。 Put it in code: 把它放在代码中:

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

From your point of view which is the best approach/tools to write fromSchemaAtoB guys? 从您的观点来看,哪个是最好的方法/工具来自SchemaAtoB人? I really want to describe transfomations using the schemas, something like: 我真的想用描述模式来描述变形,例如:

schemaB.properties.foo = schemaA.properties.dtstart

I saw a lot of basic json transformation packages but it seems to me that in most of them you specify your output as external templates that do not take into account the schemas (so result could be invalid with respect to schemaB). 我看到了许多基本的json转换包,但在我看来,在大多数情况下,您将输出指定为不考虑模式的外部模板(因此结果可能与schemaB无效)。

Thank you so much in advance!! 非常感谢你提前!!

JG JG

PS: I prefer javascript based solutions if possible but I am really open to any possibility. PS:如果可能的话,我更喜欢基于javascript的解决方案,但我对任何可能性都很开放。

EDIT 1: To clarify after reading @jason's answer, the question is how to better describe such relations between schemas and how to apply them to obtain calendarB. 编辑1:在阅读@jason的答案之后澄清一下,问题是如何更好地描述模式之间的关系以及如何应用它们来获取calendarB。 So if you prefer: 所以,如果您愿意:

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

and the question then is how to better describe "relationsAtoB" and how to implement the "transform" function. 那么问题是如何更好地描述“relationsAtoB”以及如何实现“转换”功能。

This is not something that JSON Schema is designed for. 这不是JSON Schema的设计目标。 Transforming JSON from one JSON Schema to another requires a human to provide context for the transformation. 将JSON从一个JSON模式转换为另一个JSON模式需要人为变换提供上下文。

For example, here is a fairly simple transformation for a human to do. 例如,这是一个人类要做的相当简单的转换。

jsonA jsonA

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

schemaA schemaA

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

schemaB schemaB

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

Can you figure out what the transformation should be from this information alone? 你能从这些信息中找出转变应该是什么吗? Maybe, but there are too many ambiguities for it to be done problematically. 也许吧,但是有太多的歧义可以解决问题。 This transformation converts an object to an array of key/value pairs. 此转换将对象转换为键/值对数组。

jsonB jsonB

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

Because of the ambiguity comparing schemas, just about any transformations will have to be done manually on a case-by-case basis. 由于比较模式的模糊性,几乎任何变换都必须根据具体情况手动完成。 I don't think you will get very far with this approach. 我不认为你会用这种方法走得很远。

JSON-LD JSON-LD

You might want to look into JSON-LD as an alternative. 您可能希望将JSON-LD作为替代方案。 A JSON-LD document describes data as a directed graph. JSON-LD文档将数据描述为有向图。 Consequently, there are multiple ways a JSON-LD document can be expressed as a JSON object. 因此,JSON-LD文档可以通过多种方式表示为JSON对象。 In JSON-LD, this is called framing . 在JSON-LD中,这称为框架

The idea would be to describe your calendar as a JSON-LD document that can be framed to match either schemaA or schemaB. 我们的想法是将您的日历描述为JSON-LD文档,可以将其框架化以匹配schemaA或schemaB。 To put it another way, the JSON-LD document is the context needed to remove the ambiguities between the schemas. 换句话说,JSON-LD文档是消除模式之间的歧义所需的上下文。 I would show an example, but I don't know JSON-LD that well. 我会举一个例子,但我不太了解JSON-LD。 I'll leave it to you it look into it if you think it might solve your problem. 如果你认为它可以解决你的问题,我会留给你看看它。

I believe a library like this could be used to address your question. 我相信像这样的图书馆可以用来解决你的问题。 This does not directly address the question (transforming from one JSON schema to the other) but what you can do (which is what I am currently doing) is the following: 这并没有直接解决问题(从一个JSON模式转换到另一个JSON模式),但你可以做什么(我现在正在做的)如下:

  1. Specify a JSON schema for your input 为输入指定JSON模式
  2. Specify a JSON schema for your output 为输出指定JSON模式
  3. Specify a mapping template (eg using the library I referenced). 指定映射模板(例如,使用我引用的库)。

Of course, ideally you would not have to do both 2 and 3 but I have not found something which does this automatically. 当然,理想情况下,您不必同时执行23但我没有找到自动执行此操作的内容。 So, for example, you could specify the mapping template and create some library function which takes that as well as the JSON schema in 1 as its inputs, and would generate the JSON schema in 3 as its output. 因此,例如,您可以指定映射模板并创建一些库函数,该函数将1以及1中的JSON模式作为其输入,并将在3生成JSON模式作为其输出。

This, however, is not trivial so currently I am specifying both 2 and 3 . 然而,这并非易事,所以目前我正在指定23

Also, keep in mind that you cannot have 1 and 2 and somehow automatically generate 3 . 此外,请记住,你不能有12并以某种方式自动生成3 This is because there are more than one mapping functions that would take data adhering to schema 1 and produce data adhering to schema 2 . 这是因为有多个映射函数会将数据附加到模式1并生成遵循模式2数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM