首页 > 解决方案 > 通过模板将通用 JSON 转换为 XML

问题描述

我正在尝试设计一种服务来将通用 JSON 数据表示转换为 XML 数据表示。我想到的第一个想法(我在互联网上发现的)利用了 Go 模板实用程序。

如果我有如下 JSON 数据表示:

{
  "user": {
     "name": "Luca",
     "surname": "Rossi"
  }
} 

我可以设计如下模板:

<xml>
  <user name="{{.user.name}}" surname="{{.user.surname}}" />
</xml>

生成:

<xml>
   <user name="Luca" surname="Rossi" />
</xml>

问题是:Go 需要定义一个结构,该结构声明如何编组和解组 JSON 数据表示;然而,与此同时,我想提供模板来生成 XML 作为运行时可用的服务配置。

问题是:“有可能吗”?我知道(感谢这个问题)我可以做这样的事情:

var anyJson map[string]interface{}
json.Unmarshal(bytes, &anyJson)

当我必须访问值时问题就来了:我会被要求做一个类型断言,比如

anyJson["id"].(string)

现在,例如,我可能能够通过 JSON 模式知道 anyJson["id"] 的类型,但我不知道是否可以进行参数类型断言,例如

anyJson["id"].(typeForIDFromJSONSchema)

标签: jsonxmlgotemplates

解决方案


当您解组到map[string]interface{}时,每个嵌套的 JSON 对象也将是map[string]interface{}. 因此,所包含元素的类型断言string通常可能有效,但不适用于任何struct类型 - 解组器将始终不知道您的结构。

所以我建议的两个选项是

  • 使用类型开关和类型断言“艰难地”做到这一点 - 这是可行且快速的,但并不是那么好;或者
  • 使用不同的工具,例如jsonitergjson - 这些可能会慢一些,但它们确实允许您遍历任意 JSON 图

我使用过 GJson 和 Jsoniter。GJson 通过输入逐字节读取,使用缓冲来保持其速度,提供允许检查当前元素和断言以转换值的 API。

Jsoniter 在我看来就像 Java 中成功的解析器一样的更简洁的实现,但我还没有将它用于以这种方式进行解析。(它也可以简单地用作标准 Go 的快速替代品encoding/json。)我建议你专注于使用它的Iterator和它的WhatIsNext方法。


推荐阅读