2014-07-23 33 views
5

Tôi cần chuyển đổi chuỗi Json thành cấu trúc dữ liệu bảng trong Lua. Tôi đang sử dụng mã sau đây.Chuyển đổi chuỗi JSON sang bảng Lua?

local json = require "json" 

local t = { 
    ["name1"] = "value1", 
    ["name2"] = { 1, false, true, 23.54, "a \021 string" }, 
    name3 = json.null 
} 

local encode = json.encode (t) 
print (encode) --> {"name1":"value1","name3":null,"name2":[1,false,true,23.54,"a \u0015 string"]} 

local decode = json.decode(encode) 

Nhưng khi tôi chạy kịch bản, tôi nhận được lỗi sau,

no field package.preload['json'] 
    no file '/usr/local/share/lua/5.2/json.lua' 
    no file '/usr/local/share/lua/5.2/json/init.lua' 
    no file '/usr/local/lib/lua/5.2/json.lua' 
    no file '/usr/local/lib/lua/5.2/json/init.lua' 
    no file './json.lua' 
    no file '/usr/local/lib/lua/5.2/json.so' 
    no file '/usr/local/lib/lua/5.2/loadall.so' 
    no file './json.so' 

Vậy làm thế nào để chuyển đổi chuỗi json của tôi để bàn lua?

+6

Sự cố không liên quan gì đến việc viết mã. Bạn phải cài đặt thư viện Lua "json" vào hệ thống của bạn. Điều đó có thể đơn giản như plopping xuống "./json.lua" hoặc bạn có thể lấy nó thông qua trình quản lý gói. Có một số lựa chọn có sẵn. Bạn đang sử dụng cái nào và bạn cài đặt nó như thế nào và trên hệ điều hành nào? –

+1

http://lua-users.org/wiki/JsonModules – moteus

+0

có thể bạn đang theo dõi [LuaJSON] (https://github.com/harningt/luajson/blob/master/rockspecs/luajson-1.3.1-1. rockspec) –

Trả lời

5

có thể lua-cjson là bạn của bạn:

cài đặt ví dụ: qua luarocks:

$sudo luarocks install lua-cjson 

sau đó trong lua:

local json = require('cjson') 
local tab = json.decode(json_string) 
json_string = json.encode(tab) 
1

https://gist.github.com/tylerneylon/59f4bcf316be525b30ab

tôi thấy tinh khiết tập tin script lua để phân tích dữ liệu json (chỉ là một tập tin).

local json = {} 


-- Internal functions. 

local function kind_of(obj) 
    if type(obj) ~= 'table' then return type(obj) end 
    local i = 1 
    for _ in pairs(obj) do 
    if obj[i] ~= nil then i = i + 1 else return 'table' end 
    end 
    if i == 1 then return 'table' else return 'array' end 
end 

local function escape_str(s) 
    local in_char = {'\\', '"', '/', '\b', '\f', '\n', '\r', '\t'} 
    local out_char = {'\\', '"', '/', 'b', 'f', 'n', 'r', 't'} 
    for i, c in ipairs(in_char) do 
    s = s:gsub(c, '\\' .. out_char[i]) 
    end 
    return s 
end 

-- Returns pos, did_find; there are two cases: 
-- 1. Delimiter found: pos = pos after leading space + delim; did_find = true. 
-- 2. Delimiter not found: pos = pos after leading space;  did_find = false. 
-- This throws an error if err_if_missing is true and the delim is not found. 
local function skip_delim(str, pos, delim, err_if_missing) 
    pos = pos + #str:match('^%s*', pos) 
    if str:sub(pos, pos) ~= delim then 
    if err_if_missing then 
     error('Expected ' .. delim .. ' near position ' .. pos) 
    end 
    return pos, false 
    end 
    return pos + 1, true 
end 

-- Expects the given pos to be the first character after the opening quote. 
-- Returns val, pos; the returned pos is after the closing quote character. 
local function parse_str_val(str, pos, val) 
    val = val or '' 
    local early_end_error = 'End of input found while parsing string.' 
    if pos > #str then error(early_end_error) end 
    local c = str:sub(pos, pos) 
    if c == '"' then return val, pos + 1 end 
    if c ~= '\\' then return parse_str_val(str, pos + 1, val .. c) end 
    -- We must have a \ character. 
    local esc_map = {b = '\b', f = '\f', n = '\n', r = '\r', t = '\t'} 
    local nextc = str:sub(pos + 1, pos + 1) 
    if not nextc then error(early_end_error) end 
    return parse_str_val(str, pos + 2, val .. (esc_map[nextc] or nextc)) 
end 

-- Returns val, pos; the returned pos is after the number's final character. 
local function parse_num_val(str, pos) 
    local num_str = str:match('^-?%d+%.?%d*[eE]?[+-]?%d*', pos) 
    local val = tonumber(num_str) 
    if not val then error('Error parsing number at position ' .. pos .. '.') end 
    return val, pos + #num_str 
end 


-- Public values and functions. 

function json.stringify(obj, as_key) 
    local s = {} -- We'll build the string as an array of strings to be concatenated. 
    local kind = kind_of(obj) -- This is 'array' if it's an array or type(obj) otherwise. 
    if kind == 'array' then 
    if as_key then error('Can\'t encode array as key.') end 
    s[#s + 1] = '[' 
    for i, val in ipairs(obj) do 
     if i > 1 then s[#s + 1] = ', ' end 
     s[#s + 1] = json.stringify(val) 
    end 
    s[#s + 1] = ']' 
    elseif kind == 'table' then 
    if as_key then error('Can\'t encode table as key.') end 
    s[#s + 1] = '{' 
    for k, v in pairs(obj) do 
     if #s > 1 then s[#s + 1] = ', ' end 
     s[#s + 1] = json.stringify(k, true) 
     s[#s + 1] = ':' 
     s[#s + 1] = json.stringify(v) 
    end 
    s[#s + 1] = '}' 
    elseif kind == 'string' then 
    return '"' .. escape_str(obj) .. '"' 
    elseif kind == 'number' then 
    if as_key then return '"' .. tostring(obj) .. '"' end 
    return tostring(obj) 
    elseif kind == 'boolean' then 
    return tostring(obj) 
    elseif kind == 'nil' then 
    return 'null' 
    else 
    error('Unjsonifiable type: ' .. kind .. '.') 
    end 
    return table.concat(s) 
end 

json.null = {} -- This is a one-off table to represent the null value. 

function json.parse(str, pos, end_delim) 
    pos = pos or 1 
    if pos > #str then error('Reached unexpected end of input.') end 
    local pos = pos + #str:match('^%s*', pos) -- Skip whitespace. 
    local first = str:sub(pos, pos) 
    if first == '{' then -- Parse an object. 
    local obj, key, delim_found = {}, true, true 
    pos = pos + 1 
    while true do 
     key, pos = json.parse(str, pos, '}') 
     if key == nil then return obj, pos end 
     if not delim_found then error('Comma missing between object items.') end 
     pos = skip_delim(str, pos, ':', true) -- true -> error if missing. 
     obj[key], pos = json.parse(str, pos) 
     pos, delim_found = skip_delim(str, pos, ',') 
    end 
    elseif first == '[' then -- Parse an array. 
    local arr, val, delim_found = {}, true, true 
    pos = pos + 1 
    while true do 
     val, pos = json.parse(str, pos, ']') 
     if val == nil then return arr, pos end 
     if not delim_found then error('Comma missing between array items.') end 
     arr[#arr + 1] = val 
     pos, delim_found = skip_delim(str, pos, ',') 
    end 
    elseif first == '"' then -- Parse a string. 
    return parse_str_val(str, pos + 1) 
    elseif first == '-' or first:match('%d') then -- Parse a number. 
    return parse_num_val(str, pos) 
    elseif first == end_delim then -- End of an object or array. 
    return nil, pos + 1 
    else -- Parse true, false, or null. 
    local literals = {['true'] = true, ['false'] = false, ['null'] = json.null} 
    for lit_str, lit_val in pairs(literals) do 
     local lit_end = pos + #lit_str - 1 
     if str:sub(pos, lit_end) == lit_str then return lit_val, lit_end + 1 end 
    end 
    local pos_info_str = 'position ' .. pos .. ': ' .. str:sub(pos, pos + 10) 
    error('Invalid json syntax starting at ' .. pos_info_str) 
    end 
end 

return json 
3

Bạn có thể sử dụng json-lua. Một thực hiện lua thuần túy của json. Đầu tiên cài đặt json-lua bằng cách sử dụng Luarocks. luarocks install json-lua. Sau đó, sử dụng mã này:

local json = require "json" 

local t = { 
    ["name1"] = "value1", 
    ["name2"] = { 1, false, true, 23.54, "a \021 string" }, 
    name3 = json.null 
} 

local encode = json:encode (t) 
print (encode) --> {"name1":"value1","name3":null,"name2":[1,false,true,23.54,"a \u0015 string"]} 

local decode = json:decode(encode) 

Đã xác minh & Đã xác minh trên win 7 64 bit với lua 5.1. lua-cjson là tốt, nhưng nó không phải là một loại đá lua thuần túy. Vì vậy, nó cài đặt sẽ không được dễ dàng hơn cho bạn.

Các vấn đề liên quan