如何在Lua中使用json

2023-02-28 12:33:03 浏览数 (2)

- json简介 -

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格局。它基于ECMAScript的一个子集。JSON选用完全独立于言语的文本格局,但是也使用了类似于C言语宗族的习气(包含C、C 、C#、Java、JavaScript、Perl、Python等)。这些特性使json调试成为抱负的数据交换言语。易于人阅览和编写,同时也易于机器解析和生成(一般用于提高网络传输速率)。

代码语言:javascript复制
 1. json是一种字符,与js其实没有关系。
 2. json使用了ECMAScript的对象的语法。
 3. json是一种通用数据,通用,前端和后端(php,java,python,go)。
 4. 功能:前后端数据交互。

简单来说:json就是一种在各个编程语言中流通的数据格式,负责不同编程语言中的数据传递和交互。

- JSON的格式 -

JSON 数据的书写格式是键(名称)/值对。JSON 键值对是用来保存 JS 对象的一种方式,和 JS 对象的写法也大同小异,键/值对包括字段名称(在双引号中),后面写一个冒号,然后是值。JSON 值可以是:字符串(在双引号中)、数组(在中括号中)、数字(整数或浮点数)、逻辑值(true 或 false)、对象(在大括号中)、 null。

- JSON结构 -

JSON结构有两种结构,就是对象和数组。通过这两种结构可以表示各种复杂的结构。{"province": "Shanxi"} 可以理解为是一个包含province为Shanxi的对象, ["Shanxi","Shandong"]这是一个包含两个元素的数组 而 [{“province”: "Shanxi"},{"province": "Shandong"}] 就表示包含两个对象的数组。当然了,你也可以使用 {"province":["Shanxi","Shandong"]} 来简化上面的JSON,这是一个拥有一个name数组的对象。下面是一小段JSON代码:

代码语言:javascript复制
{
  "skillz":{
    "web":[
      {
        "name":"html",
        "years":"5"
      },
      {
        "name":"css",
        "years":"3"
      }
    ],
    "database":[
      {
        "name":"sql",
        "years":"7"
      }
    ]
  }
}

花括弧,方括弧,冒号和逗号 :花括弧表示一个“容器” ,方括号装载数组 ,名称和值用冒号隔开 ,数组元素通过逗号隔开 。

- 纯Lua环境下安装cjson模块 -

简介

Lua CJSON 是 Lua 语言提供高性能的 JSON 解析器和编码器,其性能比纯 Lua 库要高 10 到 20 倍。Lua CJSON 完全支持 UTF-8 https://github.com/mpx/lua-cjson/

下载源码

lua-cjson 官方地址 https://github.com/mpx/lua-cjson/ 解压到指定目录,切换到解压后的目录,运行命令 make install

Lua转换JSON的字符串

  • encode()函数
代码语言:javascript复制
-- 加载cjson模块
local cjson = require("cjson")
-- 定义数组格式
local torigin ={"Lua","Go","PHP"} 
local mytable{}
mytable["language"] = torigin
mytable["key"]="value"
local jsondata = cjson.encode(torigin)
print(jsondata)
结果:{"key":"value","language":["Lua","Go","PHP"]}
  • decode()函数
代码语言:javascript复制
-- 加载cjson模块
local cjson = require("cjson")
local origin = '{"key1":"VALUE1","key2":"VALUE2","key3":"VALUE3","key4":{"key4_1":"VALU5_2","key4_2":"VALU5_1"},"key5":[1,2,3]}'

local data = cjson.decode(origin)
print(data)
print(data["key1"])
print(data["key2"])
print(data["key3"])
print(data["key4"]["key4_1"],data["key4"]["key4_2"])
print(data["key5"][1],data["key5"][2],data["key5"][3])

以上Lua原生在打印data的时候,由于会将json解析成table(表)数据结构,输出结果会是table: 0x558234d3e3b0,直接打印出地址, 想要查看数据只能根据键,打印值。如何优雅的输出整个解析的table结构,看一下FreeSWITCH中如何优雅的解析json。

FreeSWITCH如何使用Lua操作json

  • encode()函数
代码语言:javascript复制
-- 加载JSON模块
json = freeswitch.JSON()
-- 定义数组格式
local torigin ={"Lua","Go","PHP"} 
local mytable{}
mytable["language"] = torigin
mytable["key"]="value"
local data = json.encode(torigin)
freeswitch.consoleLog("INFO", data .. "n")
结果:{"key":"value","language":["Lua","Go","PHP"]}

代码解读:这里可能会有疑惑,代码中的freeswitch是怎么来的。这是FreeSWITCH在运行过程中,事先生成的全局变量,将JSON函数封装,赋值给了全局参数。这样可以随时使用FreeSWITCH中JSON模块,consoleLog()函数是FreeSWITCH中内置打印字符串函数。

  • decode()函数
代码语言:javascript复制
function serialize(o)
  s = ""
  if type(o) == "number" then
    s = s .. o
  elseif type(o) == "string" then
    s = s .. string.format("%q", o)
  elseif type(o) == "table" then
    s = s .. "{n"
    for k, v in pairs(o) do
      s = s .. '  ' .. k .. ' = '
      s = s .. serialize(v)
      s = s .. ",n"
    end
    s = s .. "}"
  elseif type(o) == "boolean" then
    if o then
      s = s .. "true"
    else
      s = s .. "false"
    end
  else
    s = s .. " [" .. type(o) .. "]"
  end

  return s
end

-- 加载JSON模块
json = freeswitch.JSON()
local origin = '{"a": "1", "b": 2, "c": true, "d": false, "e": [], "f": {}, "g": [1, 2, "3"], "h": {"a": 1, "b": 2}}'
local data = json.decode(origin)
freeswitch.consoleLog("INFO", serialize(data) .. "n")
-- 输出结构
{
  c = true,
  b = 2.0,
  a = "1",
  h = {
  a = 1.0,
  b = 2.0,
},
  g = {
  1 = 1.0,
  2 = 2.0,
  3 = "3",
},
  f = {
},
  e = {
},
  d = false,
}

代码解析:FreeSWITCH中serialize()函数能够优雅的输出lua中的table格式,不会存在原生Lua中只打印table地址的情况。

总结

FreeSWITCH中不只是提供了Json模块的便捷函数,同时也内置了许多常用函数的封装,也希望大家提供更多的函数的开源支持。

0 人点赞