【问题标题】:JQ: Populate json data using a json templateJQ:使用 json 模板填充 json 数据
【发布时间】:2021-11-11 07:35:19
【问题描述】:

我想将“原始”json 数据转换为其他 json 结构。

例如:

def template:
{
  "id": "$id",
  "practitioner": "$practitioner",
  "patient": {
    "name": "$patientName",
    "familyName": "$patientFamilyName"
  }
}
;

我的 data.json 是:

[
  {
    "id": "id1",
    "practitioner": {
      "practitionerKey1": "practitionerValue1",
      "practitionerKey2": "practitionerValue2"
    },
    "name": "John",
    "familyName": "Smith"
  },
  {
    "id": "id2",
    "practitioner": {
      "practitionerKey1": "practitionerValue1",
      "practitionerKey2": "practitionerValue2"
    },
    "patientName": "Samuel",
    "patientFamilyName": "Schnaider"    
  }
]

我想要的结果是:

[
  {
    "id": "id1",
    "practitioner": {
      "practitionerKey1": "practitionerValue1",
      "practitionerKey2": "practitionerValue2"
    },
    "patient": {
      "name": "John",
      "familyName": "Smith"
    }
  },
  {
    "id": "id2",
    "practitioner": {
      "practitionerKey1": "practitionerValue1",
      "practitionerKey2": "practitionerValue2"
    },
    "patient": {
      "name": "Samuel",
      "familyName": "Schnaider"
    }
  }
]

关于如何映射上述数据 json 并使用带有 JQ 的 json 模板填充它的任何想法?

【问题讨论】:

  • 您的模板有缺陷,变量没有定义。它们应该是字段名称(.id 而不是$id 等),或者您需要模板定义中的参数(例如def template($id))。否则不清楚如何应用模板。
  • 另外,data.json 输入文件的内容和您想要的结果实际上都不是正确的 JSON。不引用字段名称是 jq 语言中的简写,但它不是 JSON。
  • 报价已解决。忽略我的模板方法。我简单地认为可以使用这些替代来实现。但其实我不知道......
  • @pmf - 我认为 OP 希望模板中的“$-strings”被 JSON 中的相应键名替换。这是一种容易出错的方法,但它是可行的。
  • 可能是一个错字:数组的第一个对象有键namefamilyName,第二个有patientNamepatientFamilyName。两者都被转移到输出中patient 下的namefamilyName。因此,我在回答中假设输入数组的第一个对象在这里拼写错误。如果这确实是故意的,请纠正我。

标签: json jq


【解决方案1】:

您在问题中设想的“按示例查询”方法是可行的,尽管它容易出错(实际上正如@pmf 指出的那样,您的示例包含错误)。这是如何实现基于匹配“$-names”与键名的“QBE”方法:

def matchName($name):
   first(.. | objects | to_entries[] | select(.key == $name) | .value) // null ;

def fillin($t):
  . as $in
  | $t
  | walk(if type == "string" and startswith("$")
         then .[1:] as $s | $in | matchName($s)
         else . end);
     
map(fillin(template))

【讨论】:

    【解决方案2】:

    不管你的模板,为什么不简单地调用

    jq 'map(
      .patient = {name: .patientName, familyName: .patientFamilyName}
      | del(.patientName, .patientFamilyName)
    )' data.json
    

    Demo(为此,我根据上面comment 中描述的假定错字更正了您的输入 JSON)

    【讨论】:

    • 问题是我的真实模板非常大,我只需要更改那些字段...我认为使用某种模板很有用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-03
    • 2018-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多