Thread Tools Display Modes
10/07/19, 02:07 PM   #1
Enodoc
AddOn Author - Click to view addons
Join Date: Aug 2014
Posts: 52
JSON to Lua

Anyone have any ideas how to convert a JSON script to a Lua table so it can be read by add-ons?

Here's an example of the JSON:
Code:
{"numRecords":1,"quest":[{"id":"2345","logId":"144998164","locationId":"20246462","name":"Depths of Madness","level":"50","type":"0","repeatType":"0","displayType":"0","backgroundText":"I found a lost member of the Queen's entourage near the entrance to a hidden Vale. She told me that her fellow entourage members have been taken. A mad mage apparently holds them in the Vale.","objective":"Glister Vale","poiIndex":"4","goalText":"Talk to Eminelya","confirmText":"","declineText":"","endDialogText":"Sanessalmo? Now that name I remember. Used to be a member of the Queen's inner circle! \n\nYou have my deepest gratitude for your service today. I'll be sure the Queen learns of your bravery.","endBackgroundText":"I found a lost member of the Queen's entourage near the entrance to a hidden Vale. She told me that her fellow entourage members have been taken. A mad mage apparently holds them in the Vale.","endJournalText":"I returned to Eminelya's side. I should speak to her one last time.","isShareable":"1","numTools":"1","hasTimer":"0","timerCaption":"Depths of Madness","timerDuration":"0","numSteps":"1","numRewards":"-1","count":"19","zone":"Auridon","internalId":"4272"}]}
If that could be turned into a Lua table array, basically syntactically replacing {"":""} with {[""]=""}, then the data could be incorporated in an add-on (or even a Lib for others to use).

Thanks!
  Reply With Quote
10/07/19, 03:26 PM   #2
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,903
https://github.com/rxi/json.lua

Use Json.decode in a normal lua environment (e.g. windows cmd line) to get the data and store it in a txt file e.g., rename it to .lua for your SavedVariables or a lua file you include in your addon afterwards and load them into your addon.
  Reply With Quote
10/08/19, 04:54 AM   #3
sirinsidiator
 
sirinsidiator's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 1,566
Don't think that's enough. You'd still need to serialize it into Lua code so the game can load it.

As I see it you have two different approaches you can take. Either you convert it before the game loads it, or after.

In the first case you have to use some library that can read the JSON data and another library to serialize it into Lua code that can be read by the game. Reading the JSON data is the smallest issue here as it is well supported in plenty of languages. The problem is how to generate the Lua code. There doesn't seem to be any out of the box solutions, but then again it's not really hard to do it yourself with a few lines of code. It won't even matter which language you use for that. JS, Lua, Java - anything is fine.
If you want to avoid that problem altogether you could look for a pure Lua implementation of a JSON library, write a small addon that takes JSON in a text field, put it into a saved variable and let the game serialize it for you.

The other way would be to simply dump the JSON string into a Lua string and then deserialize it at runtime with said pure Lua implementation of a JSON library. That may be a bit simpler in terms of complexity, but may cause performance issues depending on how much data you want to load that way.
  Reply With Quote
10/08/19, 05:37 AM   #4
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,903
Wouldn't maybe this do the lua stuff for you (using the json lua library mentioned above):
Lua Code:
  1. print(json.decode(jsonString).variable)

Not sure though if one can send this to a file from lua

Or maybe the script taken from this link (https://gist.github.com/tylerneylon/...f316be525b30ab) helps:

Put it in a file called (for example) json.lua, and include it in your project with something like json = require "json"
Lua Code:
  1. local json = {}
  2.  
  3.  
  4. -- Internal functions.
  5.  
  6. local function kind_of(obj)
  7.   if type(obj) ~= 'table' then return type(obj) end
  8.   local i = 1
  9.   for _ in pairs(obj) do
  10.     if obj[i] ~= nil then i = i + 1 else return 'table' end
  11.   end
  12.   if i == 1 then return 'table' else return 'array' end
  13. end
  14.  
  15. local function escape_str(s)
  16.   local in_char  = {'\\', '"', '/', '\b', '\f', '\n', '\r', '\t'}
  17.   local out_char = {'\\', '"', '/',  'b',  'f',  'n',  'r',  't'}
  18.   for i, c in ipairs(in_char) do
  19.     s = s:gsub(c, '\\' .. out_char[i])
  20.   end
  21.   return s
  22. end
  23.  
  24. -- Returns pos, did_find; there are two cases:
  25. -- 1. Delimiter found: pos = pos after leading space + delim; did_find = true.
  26. -- 2. Delimiter not found: pos = pos after leading space;     did_find = false.
  27. -- This throws an error if err_if_missing is true and the delim is not found.
  28. local function skip_delim(str, pos, delim, err_if_missing)
  29.   pos = pos + #str:match('^%s*', pos)
  30.   if str:sub(pos, pos) ~= delim then
  31.     if err_if_missing then
  32.       error('Expected ' .. delim .. ' near position ' .. pos)
  33.     end
  34.     return pos, false
  35.   end
  36.   return pos + 1, true
  37. end
  38.  
  39. -- Expects the given pos to be the first character after the opening quote.
  40. -- Returns val, pos; the returned pos is after the closing quote character.
  41. local function parse_str_val(str, pos, val)
  42.   val = val or ''
  43.   local early_end_error = 'End of input found while parsing string.'
  44.   if pos > #str then error(early_end_error) end
  45.   local c = str:sub(pos, pos)
  46.   if c == '"'  then return val, pos + 1 end
  47.   if c ~= '\\' then return parse_str_val(str, pos + 1, val .. c) end
  48.   -- We must have a \ character.
  49.   local esc_map = {b = '\b', f = '\f', n = '\n', r = '\r', t = '\t'}
  50.   local nextc = str:sub(pos + 1, pos + 1)
  51.   if not nextc then error(early_end_error) end
  52.   return parse_str_val(str, pos + 2, val .. (esc_map[nextc] or nextc))
  53. end
  54.  
  55. -- Returns val, pos; the returned pos is after the number's final character.
  56. local function parse_num_val(str, pos)
  57.   local num_str = str:match('^-?%d+%.?%d*[eE]?[+-]?%d*', pos)
  58.   local val = tonumber(num_str)
  59.   if not val then error('Error parsing number at position ' .. pos .. '.') end
  60.   return val, pos + #num_str
  61. end
  62.  
  63.  
  64. -- Public values and functions.
  65.  
  66. function json.stringify(obj, as_key)
  67.   local s = {}  -- We'll build the string as an array of strings to be concatenated.
  68.   local kind = kind_of(obj)  -- This is 'array' if it's an array or type(obj) otherwise.
  69.   if kind == 'array' then
  70.     if as_key then error('Can\'t encode array as key.') end
  71.     s[#s + 1] = '['
  72.     for i, val in ipairs(obj) do
  73.       if i > 1 then s[#s + 1] = ', ' end
  74.       s[#s + 1] = json.stringify(val)
  75.     end
  76.     s[#s + 1] = ']'
  77.   elseif kind == 'table' then
  78.     if as_key then error('Can\'t encode table as key.') end
  79.     s[#s + 1] = '{'
  80.     for k, v in pairs(obj) do
  81.       if #s > 1 then s[#s + 1] = ', ' end
  82.       s[#s + 1] = json.stringify(k, true)
  83.       s[#s + 1] = ':'
  84.       s[#s + 1] = json.stringify(v)
  85.     end
  86.     s[#s + 1] = '}'
  87.   elseif kind == 'string' then
  88.     return '"' .. escape_str(obj) .. '"'
  89.   elseif kind == 'number' then
  90.     if as_key then return '"' .. tostring(obj) .. '"' end
  91.     return tostring(obj)
  92.   elseif kind == 'boolean' then
  93.     return tostring(obj)
  94.   elseif kind == 'nil' then
  95.     return 'null'
  96.   else
  97.     error('Unjsonifiable type: ' .. kind .. '.')
  98.   end
  99.   return table.concat(s)
  100. end
  101.  
  102. json.null = {}  -- This is a one-off table to represent the null value.
  103.  
  104. function json.parse(str, pos, end_delim)
  105.   pos = pos or 1
  106.   if pos > #str then error('Reached unexpected end of input.') end
  107.   local pos = pos + #str:match('^%s*', pos)  -- Skip whitespace.
  108.   local first = str:sub(pos, pos)
  109.   if first == '{' then  -- Parse an object.
  110.     local obj, key, delim_found = {}, true, true
  111.     pos = pos + 1
  112.     while true do
  113.       key, pos = json.parse(str, pos, '}')
  114.       if key == nil then return obj, pos end
  115.       if not delim_found then error('Comma missing between object items.') end
  116.       pos = skip_delim(str, pos, ':', true)  -- true -> error if missing.
  117.       obj[key], pos = json.parse(str, pos)
  118.       pos, delim_found = skip_delim(str, pos, ',')
  119.     end
  120.   elseif first == '[' then  -- Parse an array.
  121.     local arr, val, delim_found = {}, true, true
  122.     pos = pos + 1
  123.     while true do
  124.       val, pos = json.parse(str, pos, ']')
  125.       if val == nil then return arr, pos end
  126.       if not delim_found then error('Comma missing between array items.') end
  127.       arr[#arr + 1] = val
  128.       pos, delim_found = skip_delim(str, pos, ',')
  129.     end
  130.   elseif first == '"' then  -- Parse a string.
  131.     return parse_str_val(str, pos + 1)
  132.   elseif first == '-' or first:match('%d') then  -- Parse a number.
  133.     return parse_num_val(str, pos)
  134.   elseif first == end_delim then  -- End of an object or array.
  135.     return nil, pos + 1
  136.   else  -- Parse true, false, or null.
  137.     local literals = {['true'] = true, ['false'] = false, ['null'] = json.null}
  138.     for lit_str, lit_val in pairs(literals) do
  139.       local lit_end = pos + #lit_str - 1
  140.       if str:sub(pos, lit_end) == lit_str then return lit_val, lit_end + 1 end
  141.     end
  142.     local pos_info_str = 'position ' .. pos .. ': ' .. str:sub(pos, pos + 10)
  143.     error('Invalid json syntax starting at ' .. pos_info_str)
  144.   end
  145. end

Last edited by Baertram : 10/08/19 at 05:39 AM.
  Reply With Quote

ESOUI » Developer Discussions » Lua/XML Help » JSON to Lua

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off