GOLANG 中复杂 JSON 解析

本贴最后更新于 2611 天前,其中的信息可能已经时移世改

在使用 golang 的时候, 很烦处理 json 数据, 感觉问题不断啊
so: 记录在此, 以便查看 ~

在 encoding/json 包下有提供的方法: Unmarshal
文档中是这样描述的:

  Unmarshal函数解析json编码的数据并将结果存入v指向的值。
  Unmarshal和Marshal做相反的操作,必要时申请映射、切片或指针,有如下的附加规则:
  要将json数据解码写入一个指针,Unmarshal函数首先处理json数据是json字面值null的情况。此时,函数将指针设为nil;否则,函数将json数据解码写入指针指向的值;如果指针本身是nil,函数会先申请一个值并使指针指向它。
  要将json数据解码写入一个结构体,函数会匹配输入对象的键和Marshal使用的键(结构体字段名或者它的标签指定的键名),优先选择精确的匹配,但也接受大小写不敏感的匹配。
  要将json数据解码写入一个接口类型值,函数会将数据解码为如下类型写入接口:

   Bool                   对应JSON布尔类型
   float64                对应JSON数字类型
   string                 对应JSON字符串类型
   []interface{}          对应JSON数组
   map[string]interface{} 对应JSON对象
   nil                    对应JSON的null

  如果一个JSON值不匹配给出的目标类型,或者如果一个json数字写入目标类型时溢出,Unmarshal函数会跳过该字段并尽量完成其余的解码操作。如果没有出现更加严重的错误,本函数会返回一个描述第一个此类错误的详细信息的UnmarshalTypeError。
  JSON的null值解码为go的接口、指针、切片时会将它们设为nil,因为null在json里一般表示“不存在”。 解码json的null值到其他go类型时,不会造成任何改变,也不会产生错误。
  当解码字符串时,不合法的utf-8或utf-16代理(字符)对不视为错误,而是将非法字符替换为unicode字符U+FFFD。

大多时间开发中会用到解析 json string 到 struct 便与管理和调用

json:

{
  "style": 3,
  "color": "black",
  "width": 300,
  "height": 200
}

go

type BoxStruct struct {
	Style  int
	Color  string
	Width  float64
	Height float64
}

var box BoxStruct
if err := json.Unmarshal([]byte(jsonStr), &box); err == nil {
	fmt.Println("%+b", box)
}

这个只是简单的 json 与 struct 的转换, 往往在处理的时候, 这个 box 并不是 box, 而是 boxes 只需要其声明为数组即可

var boxes []BoxStruct

前段时间开发过程中, 还遇到了一个极为复杂的 json 结构处理, 数据结构大概是这样:

{
	"box-count-6572615": {
	  "style": 1,
	  "sample": [
			{
			  "pic": "filenamebox-count-6572615",
			  "title": "yaoyi",
			  "entitle": "",
			  "describe": "",
			  "describePic": null,
			  "coordinate": [
				   {
					  "X": 55.033557046979865,
					  "Y": 33.63095238095239,
					  "title": "yaoyi",
					  "content": "yaoyi"
				    }
			    ]
		   },
		   {
			  "pic": "filename2box-count-6572615",
			  "title": "yaoyi",
			  "entitle": "",
			  "describe": "",
			  "describePic": null,
			  "coordinate": [
				  {
					  "X": 59.06040268456376,
					  "Y": 39.88095238095239,
					  "title": "yaoyi",
					  "content": "yaoyi"
				  }
			   ]
		    }
	    ]
	},
	"box-count-6605461": {
		"style": 2,
		"sample": [
			{
				"pic": "filenamebox-count-6605461",
				"title": "yaoyi",
				"entitle": "",
				"describe": "",
				"describePic": "describefilebox-count-6605461",
				"coordinate": [
					{
						"X": 48.821548821548824,
						"Y": 51.78571428571429,
						"title": "yaoyi",
						"content": "yaoyi"
					}
				]
			}
		]
	}
}

注意 JSON 的 key 值不是固定值 那么

map[string]interfalce{}

是跑不了了, 其结构就为 map[ string: struct{ array[ struct{} ] } ]
将其拆解为独个的 struct 然后组合起来
struct

type boxStruct struct {
	Style  int            `json:"style"`
	Sample []sampleStruct `json:"sample"`
}

type sampleStruct struct {
	Pic         string             `json:"pic"`
	Title       string             `json:"title"`
	Entitle     string             `json:"entitle"`
	Describe    string             `json:"describe"`
	DescribePic string             `json:"describePic"`
	Coordinate  []coordinateStruct `json:"coordinate"`
}

type coordinateStruct struct {
	X       float64 `json:"X"`
	Y       float64 `json:"Y"`
	Title   string  `json:"title"`
	Content string  `json:"content"`
}

boxStruct 就是我们需要的结构体了

go

var boxes map[string]boxStruct
if err := json.Unmarshal([]byte(jsonStr), &boxes); err == nil {
	fmt.Println("%+b", boxes)
}

THE END.

from Green
  • golang

    Go 语言是 Google 推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发 Go,是因为过去 10 多年间软件开发的难度令人沮丧。Go 是谷歌 2009 发布的第二款编程语言。

    492 引用 • 1384 回帖 • 356 关注
  • JSON

    JSON (JavaScript Object Notation)是一种轻量级的数据交换格式。易于人类阅读和编写。同时也易于机器解析和生成。

    51 引用 • 190 回帖 • 2 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • xhaoxiong

    这是一个实用的工具 http://goolibs.com/tools

    1 回复
  • 其他回帖
  • zonghua

    如果少了键是不是就直接返回错误的?

    1 回复
  • K
    作者

    并不会, 会变为 : 部分解析

  • K
    作者

    已收藏〜 👍

K
暴风雨之后,不止没看到彩虹,还感冒了。 上海

推荐标签 标签

  • Vditor

    Vditor 是一款浏览器端的 Markdown 编辑器,支持所见即所得、即时渲染(类似 Typora)和分屏预览模式。它使用 TypeScript 实现,支持原生 JavaScript、Vue、React 和 Angular。

    322 引用 • 1687 回帖 • 2 关注
  • 强迫症

    强迫症(OCD)属于焦虑障碍的一种类型,是一组以强迫思维和强迫行为为主要临床表现的神经精神疾病,其特点为有意识的强迫和反强迫并存,一些毫无意义、甚至违背自己意愿的想法或冲动反反复复侵入患者的日常生活。

    15 引用 • 161 回帖 • 1 关注
  • Docker

    Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的操作系统上。容器完全使用沙箱机制,几乎没有性能开销,可以很容易地在机器和数据中心中运行。

    479 引用 • 902 回帖
  • Sym

    Sym 是一款用 Java 实现的现代化社区(论坛/BBS/社交网络/博客)系统平台。

    下一代的社区系统,为未来而构建

    523 引用 • 4588 回帖 • 689 关注
  • Shell

    Shell 脚本与 Windows/Dos 下的批处理相似,也就是用各类命令预先放入到一个文件中,方便一次性执行的一个程序文件,主要是方便管理员进行设置或者管理用的。但是它比 Windows 下的批处理更强大,比用其他编程程序编辑的程序效率更高,因为它使用了 Linux/Unix 下的命令。

    122 引用 • 73 回帖
  • Ant-Design

    Ant Design 是服务于企业级产品的设计体系,基于确定和自然的设计价值观上的模块化解决方案,让设计者和开发者专注于更好的用户体验。

    17 引用 • 23 回帖 • 2 关注
  • CSDN

    CSDN (Chinese Software Developer Network) 创立于 1999 年,是中国的 IT 社区和服务平台,为中国的软件开发者和 IT 从业者提供知识传播、职业发展、软件开发等全生命周期服务,满足他们在职业发展中学习及共享知识和信息、建立职业发展社交圈、通过软件开发实现技术商业化等刚性需求。

    14 引用 • 155 回帖
  • Elasticsearch

    Elasticsearch 是一个基于 Lucene 的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于 RESTful 接口。Elasticsearch 是用 Java 开发的,并作为 Apache 许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

    116 引用 • 99 回帖 • 266 关注
  • 禅道

    禅道是一款国产的开源项目管理软件,她的核心管理思想基于敏捷方法 scrum,内置了产品管理和项目管理,同时又根据国内研发现状补充了测试管理、计划管理、发布管理、文档管理、事务管理等功能,在一个软件中就可以将软件研发中的需求、任务、bug、用例、计划、发布等要素有序的跟踪管理起来,完整地覆盖了项目管理的核心流程。

    5 引用 • 15 回帖 • 200 关注
  • HBase

    HBase 是一个分布式的、面向列的开源数据库,该技术来源于 Fay Chang 所撰写的 Google 论文 “Bigtable:一个结构化数据的分布式存储系统”。就像 Bigtable 利用了 Google 文件系统所提供的分布式数据存储一样,HBase 在 Hadoop 之上提供了类似于 Bigtable 的能力。

    17 引用 • 6 回帖 • 48 关注
  • Quicker

    Quicker 您的指尖工具箱!操作更少,收获更多!

    22 引用 • 81 回帖 • 1 关注
  • CloudFoundry

    Cloud Foundry 是 VMware 推出的业界第一个开源 PaaS 云平台,它支持多种框架、语言、运行时环境、云平台及应用服务,使开发人员能够在几秒钟内进行应用程序的部署和扩展,无需担心任何基础架构的问题。

    5 引用 • 18 回帖 • 155 关注
  • 心情

    心是产生任何想法的源泉,心本体会陷入到对自己本体不能理解的状态中,因为心能产生任何想法,不能分出对错,不能分出自己。

    59 引用 • 369 回帖 • 1 关注
  • MongoDB

    MongoDB(来自于英文单词“Humongous”,中文含义为“庞大”)是一个基于分布式文件存储的数据库,由 C++ 语言编写。旨在为应用提供可扩展的高性能数据存储解决方案。MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似 JSON 的 BSON 格式,因此可以存储比较复杂的数据类型。

    90 引用 • 59 回帖 • 3 关注
  • IBM

    IBM(国际商业机器公司)或万国商业机器公司,简称 IBM(International Business Machines Corporation),总公司在纽约州阿蒙克市。1911 年托马斯·沃森创立于美国,是全球最大的信息技术和业务解决方案公司,拥有全球雇员 30 多万人,业务遍及 160 多个国家和地区。

    16 引用 • 53 回帖 • 120 关注
  • 以太坊

    以太坊(Ethereum)并不是一个机构,而是一款能够在区块链上实现智能合约、开源的底层系统。以太坊是一个平台和一种编程语言 Solidity,使开发人员能够建立和发布下一代去中心化应用。 以太坊可以用来编程、分散、担保和交易任何事物:投票、域名、金融交易所、众筹、公司管理、合同和知识产权等等。

    34 引用 • 367 回帖 • 1 关注
  • 电影

    这是一个不能说的秘密。

    120 引用 • 597 回帖
  • Gzip

    gzip (GNU zip)是 GNU 自由软件的文件压缩程序。我们在 Linux 中经常会用到后缀为 .gz 的文件,它们就是 Gzip 格式的。现今已经成为互联网上使用非常普遍的一种数据压缩格式,或者说一种文件格式。

    9 引用 • 12 回帖 • 118 关注
  • React

    React 是 Facebook 开源的一个用于构建 UI 的 JavaScript 库。

    192 引用 • 291 回帖 • 440 关注
  • ZooKeeper

    ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby 一个开源的实现,是 Hadoop 和 HBase 的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

    59 引用 • 29 回帖 • 19 关注
  • Bootstrap

    Bootstrap 是 Twitter 推出的一个用于前端开发的开源工具包。它由 Twitter 的设计师 Mark Otto 和 Jacob Thornton 合作开发,是一个 CSS / HTML 框架。

    18 引用 • 33 回帖 • 684 关注
  • LeetCode

    LeetCode(力扣)是一个全球极客挚爱的高质量技术成长平台,想要学习和提升专业能力从这里开始,充足技术干货等你来啃,轻松拿下 Dream Offer!

    209 引用 • 72 回帖
  • SendCloud

    SendCloud 由搜狐武汉研发中心孵化的项目,是致力于为开发者提供高质量的触发邮件服务的云端邮件发送平台,为开发者提供便利的 API 接口来调用服务,让邮件准确迅速到达用户收件箱并获得强大的追踪数据。

    2 引用 • 8 回帖 • 446 关注
  • Jenkins

    Jenkins 是一套开源的持续集成工具。它提供了非常丰富的插件,让构建、部署、自动化集成项目变得简单易用。

    51 引用 • 37 回帖
  • Q&A

    提问之前请先看《提问的智慧》,好的问题比好的答案更有价值。

    6717 引用 • 30150 回帖 • 245 关注
  • 微信

    腾讯公司 2011 年 1 月 21 日推出的一款手机通讯软件。用户可以通过摇一摇、搜索号码、扫描二维码等添加好友和关注公众平台,同时可以将自己看到的精彩内容分享到微信朋友圈。

    129 引用 • 793 回帖
  • 脑图

    脑图又叫思维导图,是表达发散性思维的有效图形思维工具 ,它简单却又很有效,是一种实用性的思维工具。

    21 引用 • 58 回帖