Scripting Moderators ds1-e Posted March 29, 2019 Scripting Moderators Share Posted March 29, 2019 Hey. As title says, which thing is better, xml or json? I want to save player settings in player cache. - What is more efficient? - What is easier to use? If you can, i would like to see an example how to use both. Link to comment
Administrators Lpsd Posted March 29, 2019 Administrators Share Posted March 29, 2019 Currently, JSON is better for something like that. You can store that information in a database (which is way more efficient than reading/writing XML files) I would give an example, but there really isn't much to show. 1 Link to comment
Moderators Patrick Posted March 29, 2019 Moderators Share Posted March 29, 2019 (edited) I also think JSON is better and simpler. local table = { [1] = "asd", [2] = "qwe", } local JSON = toJSON(table) -- convert table to JSON. (JSON is a string, you need to store that like a string) print(JSON) -- you can print it local table_again = fromJSON(JSON) -- convert JSON back to table -- table and table_again is equal Edited March 29, 2019 by stPatrick 1 Link to comment
XaskeL Posted March 29, 2019 Share Posted March 29, 2019 JSON is simpler, but it has its limits and data size. For example, I was faced with the fact that JSON returned an empty table from a very large JSON. Here for each situation individually. Personally, I would prefer to write something small in JSON. In other cases, come up with something more rational. 1 Link to comment
Scripting Moderators ds1-e Posted March 29, 2019 Author Scripting Moderators Share Posted March 29, 2019 41 minutes ago, XaskeL said: JSON is simpler, but it has its limits and data size. For example, I was faced with the fact that JSON returned an empty table from a very large JSON. Here for each situation individually. Personally, I would prefer to write something small in JSON. In other cases, come up with something more rational. I will need just save a few settings for player, nothing big. I'll try it out, thank you guys for answers. Link to comment
Moderators IIYAMA Posted March 29, 2019 Moderators Share Posted March 29, 2019 (edited) XML has most of the cons. It is also much older, so it is to be expected. There are a few XML haters on the community, so I will keep it short. So a few pro's: - Readability is very high, especially in case of inheritance. In JSON that can also be good, but you will need a proper reader for that. - Maintenance. In case of breaking it, it is very easy to fix it. (That being said, it breaks easier if you do not know the rules.) - Saving JSON inside the notes and keeping a secondary XML layer of properties that do not have to be saved in your main data. There are not many user cases where you want that on clientside. Unless you have a shared settings file for all resources. In that case you only have to parse JSON of a specific resource node. - (not related to player settings) Can be use for multiple files that are already integrated in mta. XML, map, (acl*) So JSON? Yes, if you keep your lua table it's structure: arrays and object separated. Edited March 29, 2019 by IIYAMA 1 1 Link to comment
Scripting Moderators ds1-e Posted March 30, 2019 Author Scripting Moderators Share Posted March 30, 2019 14 hours ago, IIYAMA said: XML has most of the cons. It is also much older, so it is to be expected. There are a few XML haters on the community, so I will keep it short. So a few pro's: - Readability is very high, especially in case of inheritance. In JSON that can also be good, but you will need a proper reader for that. - Maintenance. In case of breaking it, it is very easy to fix it. (That being said, it breaks easier if you do not know the rules.) - Saving JSON inside the notes and keeping a secondary XML layer of properties that do not have to be saved in your main data. There are not many user cases where you want that on clientside. Unless you have a shared settings file for all resources. In that case you only have to parse JSON of a specific resource node. - (not related to player settings) Can be use for multiple files that are already integrated in mta. XML, map, (acl*) So JSON? Yes, if you keep your lua table it's structure: arrays and object separated. Yes, i will try it out, if i wouldn't understand something, i'll give you answer in this topic. Link to comment
savour Posted March 30, 2019 Share Posted March 30, 2019 actually if you don't know both of them, i'd say go with XML for now. and here is an example 1 Link to comment
Scripting Moderators ds1-e Posted March 30, 2019 Author Scripting Moderators Share Posted March 30, 2019 5 hours ago, savour said: actually if you don't know both of them, i'd say go with XML for now. and here is an example Hmm, but i heard that XML isn't that efficient, is that related in anyway with saving player settings in cache? Or this doesn't change anything? I mean in server efficienty. Link to comment
Moderators IIYAMA Posted March 30, 2019 Moderators Share Posted March 30, 2019 51 minutes ago, majqq said: Hmm, but i heard that XML isn't that efficient, is that related in anyway with saving player settings in cache? Or this doesn't change anything? I mean in server efficienty. It is less efficient because: - Tables are a very different format than XML. That means that you have to write and convert the data with a lot more extra code. - It isn't compact, the filesize will be a lot bigger incompare to JSON. 2 1 Link to comment
Scripting Moderators ds1-e Posted April 1, 2019 Author Scripting Moderators Share Posted April 1, 2019 On 30/03/2019 at 22:33, IIYAMA said: It is less efficient because: - Tables are a very different format than XML. That means that you have to write and convert the data with a lot more extra code. - It isn't compact, the filesize will be a lot bigger incompare to JSON. Well looks like i almost finished it in JSON, but it shows me nil, whenever i want to retrieve data. Can u help me with that? -- onClientResourceStart if fileExists("settings") then local settingsFile = fileOpen("settings") if settingsFile then local loadSettings = fileRead(settingsFile, fileGetSize(settingsFile)) local loadedData = fromJSON(loadSettings) fileClose(settingsFile) end end end addEventHandler("onClientResourceStart", resourceRoot, onClientResourceStart) -- settings json file [ { "7": false, "1": "Test item", "2": false, "4": false, "8": false, "9": false, "5": false, "10": false, "3": false, "6": false } ] -- table structure which is saved playerData = {playerItems = {[1] = false, [2] = false, [3] = false, [4] = false, [5] = false, [6] = false, [7] = false, [8] = false, [9] = false, [10] = false}} Link to comment
Moderators Patrick Posted April 1, 2019 Moderators Share Posted April 1, 2019 5 minutes ago, majqq said: Well looks like i almost finished it in JSON, but it shows me nil, whenever i want to retrieve data. Can u help me with that? -- onClientResourceStart if fileExists("settings") then local settingsFile = fileOpen("settings") if settingsFile then local loadSettings = fileRead(settingsFile, fileGetSize(settingsFile)) local loadedData = fromJSON(loadSettings) fileClose(settingsFile) end end end addEventHandler("onClientResourceStart", resourceRoot, onClientResourceStart) -- settings json file [ { "7": false, "1": "Test item", "2": false, "4": false, "8": false, "9": false, "5": false, "10": false, "3": false, "6": false } ] -- table structure which is saved playerData = {playerItems = {[1] = false, [2] = false, [3] = false, [4] = false, [5] = false, [6] = false, [7] = false, [8] = false, [9] = false, [10] = false}} You forgot the file format Link to comment
Scripting Moderators ds1-e Posted April 1, 2019 Author Scripting Moderators Share Posted April 1, 2019 (edited) 22 minutes ago, stPatrick said: You forgot the file format Well, i want this file without a format (i think it's possible, i saw settings files without format), it saves normal, load normal, but i don't know how to retrieve data after loading it. For some reason sometimes json file without any changes looks like that, you should look at the end of line, is it intended? -- settings json file [ { "7": false, "1": false, "2": false, "4": false, "8": false, "9": false, "5": false, "10": false, "3": false, "6": false } ]se } ] Maybe something wrong is in saving? This is the same onClientResourceStart, just first lines. function onClientResourceStart() if not fileExists("settings") then local settingsFile = fileCreate("settings") if settingsFile then local jsonData = toJSON(playerData.playerItems) fileWrite(settingsFile, jsonData) fileClose(settingsFile) end end -- later loading function. addEventHandler("onClientResourceStart", resourceRoot, onClientResourceStart) Edited April 1, 2019 by majqq Link to comment
Moderators IIYAMA Posted April 1, 2019 Moderators Share Posted April 1, 2019 1 hour ago, majqq said: Well looks like i almost finished it in JSON, but it shows me nil, whenever i want to retrieve data. Can u help me with that? -- onClientResourceStart if fileExists("settings") then local settingsFile = fileOpen("settings") if settingsFile then local loadSettings = fileRead(settingsFile, fileGetSize(settingsFile)) local loadedData = fromJSON(loadSettings) fileClose(settingsFile) end end end addEventHandler("onClientResourceStart", resourceRoot, onClientResourceStart) -- settings json file [ { "7": false, "1": "Test item", "2": false, "4": false, "8": false, "9": false, "5": false, "10": false, "3": false, "6": false } ] -- table structure which is saved playerData = {playerItems = {[1] = false, [2] = false, [3] = false, [4] = false, [5] = false, [6] = false, [7] = false, [8] = false, [9] = false, [10] = false}} As I mentioned before, do not mix arrays and objects in same table in Lua. For some unknown reason that has happend here. The json I am looking at contains an object instead of an array. Object: { } Array: [ ] Try to not assign the items to specific indexes, but keep it untouched. In your current code the items can be accessed using a string "1", "2" etc. Use: iprint to figure out more info. 1 1 Link to comment
Addlibs Posted April 1, 2019 Share Posted April 1, 2019 In which scope does it appear as nil? Right after loading it or later on somewhere else? I have a feeling this is about scope of variables: you load the data into a local variable which means it's only accessible in that same scope/block/function you're working in. Have you tried adding a debug output for 'loadedData' right after fromJSON'ing it? 1 Link to comment
Scripting Moderators ds1-e Posted April 1, 2019 Author Scripting Moderators Share Posted April 1, 2019 (edited) 4 hours ago, MrTasty said: In which scope does it appear as nil? Right after loading it or later on somewhere else? I have a feeling this is about scope of variables: you load the data into a local variable which means it's only accessible in that same scope/block/function you're working in. Have you tried adding a debug output for 'loadedData' right after fromJSON'ing it? It returns a table. 4 hours ago, IIYAMA said: As I mentioned before, do not mix arrays and objects in same table in Lua. For some unknown reason that has happend here. The json I am looking at contains an object instead of an array. Object: { } Array: [ ] Try to not assign the items to specific indexes, but keep it untouched. In your current code the items can be accessed using a string "1", "2" etc. Use: iprint to figure out more info. I am a bit confused, sorry if i misunderstood you. -- an other table playerItems = { fastkey_1 = false, fastkey_2 = false, fastkey_3 = false, fastkey_4 = false, fastkey_5 = false, fastkey_6 = false, fastkey_7 = false, fastkey_8 = false, fastkey_9 = false, fastkey_10 = false } And result.. [ { "fastkey_7": false, "fastkey_10": false, "fastkey_1": false, "fastkey_5": false, "fastkey_4": false, "fastkey_6": false, "fastkey_8": false, "fastkey_3": false, "fastkey_9": false, "fastkey_2": false } ]se } ] Edited April 1, 2019 by majqq Link to comment
Scripting Moderators ds1-e Posted April 1, 2019 Author Scripting Moderators Share Posted April 1, 2019 (edited) 32 minutes ago, majqq said: It returns a table. I am a bit confused, sorry if i misunderstood you. -- an other table playerItems = { fastkey_1 = false, fastkey_2 = false, fastkey_3 = false, fastkey_4 = false, fastkey_5 = false, fastkey_6 = false, fastkey_7 = false, fastkey_8 = false, fastkey_9 = false, fastkey_10 = false } And result.. [ { "fastkey_7": false, "fastkey_10": false, "fastkey_1": false, "fastkey_5": false, "fastkey_4": false, "fastkey_6": false, "fastkey_8": false, "fastkey_3": false, "fastkey_9": false, "fastkey_2": false } ]se } ] By the way i probably learned how to load data from JSON file, but i'm thinking if this thing which are you talking about can broke file. Edited April 1, 2019 by majqq Link to comment
Moderators IIYAMA Posted April 1, 2019 Moderators Share Posted April 1, 2019 (edited) @majqq Oke let me explain you the difference between Lua tables and objects / arrays in JavaScript. (JSON = JavaScript Object Notation) Here we have a table with array structure in Lua: local thisArray = {1, 2, 3, 4} Here we have a table with object structure in Lua: local thisObject = {a = 1, b = 2, c = 3, d = 4} Here we have a table with an mixed structure in Lua: local thisMix = {a = 1, b = 2, 3, 4} As you can see those are tables. There is no such thing as arrays or objects in Lua. But if we were to transform them to JavaScript: Array const thisArray = [1, 2, 3, 4]; Object const thisObject = {a: 1, b: 2, c: 3, d: 4}; There is NO mixed in JavaScript! If you insert a mixed Lua table in JSON (JavaScript Object Notation), the structure will be an OBJECT Afaik this is what is happening to you, except it doesn't look like you are doing the same thing... local thisMix = {a = 1, b = 2, 3, 4} To JSON .................... From JSON local thisMix = {a = 1, b = 2, ["1"] = 3, ["2"] = 4} -- or local thisMix = {["a"] = 1, ["b"] = 2, ["1"] = 3, ["2"] = 4} So how about try it without defining any keys. Because I really have no other idea why else it would change it to an object. playerData = {playerItems = {false, false, false, false, false, false, false, false, false, false}} Edited April 1, 2019 by IIYAMA 1 1 Link to comment
Scripting Moderators ds1-e Posted April 1, 2019 Author Scripting Moderators Share Posted April 1, 2019 (edited) 1 hour ago, IIYAMA said: @majqq Oke let me explain you the difference between Lua tables and objects / arrays in JavaScript. (JSON = JavaScript Object Notation) Here we have a table with array structure in Lua: local thisArray = {1, 2, 3, 4} Here we have a table with object structure in Lua: local thisObject = {a = 1, b = 2, c = 3, d = 4} Here we have a table with an mixed structure in Lua: local thisMix = {a = 1, b = 2, 3, 4} As you can see those are tables. There is no such thing as arrays or objects in Lua. But if we were to transform them to JavaScript: Array const thisArray = [1, 2, 3, 4]; Object const thisObject = {a: 1, b: 2, c: 3, d: 4}; There is NO mixed in JavaScript! If you insert a mixed Lua table in JSON (JavaScript Object Notation), the structure will be an OBJECT Afaik this is what is happening to you, except it doesn't look like you are doing the same thing... local thisMix = {a = 1, b = 2, 3, 4} To JSON .................... From JSON local thisMix = {a = 1, b = 2, ["1"] = 3, ["2"] = 4} -- or local thisMix = {["a"] = 1, ["b"] = 2, ["1"] = 3, ["2"] = 4} So how about try it without defining any keys. Because I really have no other idea why else it would change it to an object. playerData = {playerItems = {false, false, false, false, false, false, false, false, false, false}} [ [ false, false, false, false, false, false, false, false, false, false ] ]se ] ] And this is result. :v Maybe i should use XML? Edited April 1, 2019 by majqq Link to comment
Scripting Moderators ds1-e Posted April 1, 2019 Author Scripting Moderators Share Posted April 1, 2019 Maybe something wrong is here. Cannot edit my post above. function onClientResourceStop() if fileExists("settings") then local settingsFile = fileOpen("settings") if settingsFile then local jsonData = toJSON(playerData.playerItems) fileWrite(settingsFile, jsonData) fileClose(settingsFile) end end end addEventHandler("onClientResourceStop", getRootElement(), onClientResourceStop) Link to comment
Moderators IIYAMA Posted April 1, 2019 Moderators Share Posted April 1, 2019 (edited) It looks fine, except for: (not sure if it is your typo) [ [ false, false, false, false, false, false, false, false, false, false ] ]se ] ] What happens if you debug: jsonData ? @majqq P.s don't forget to clean the file before testing again. Oh and use resourceRoot for the even handler Edited April 1, 2019 by IIYAMA 1 1 Link to comment
Scripting Moderators ds1-e Posted April 1, 2019 Author Scripting Moderators Share Posted April 1, 2019 (edited) 6 minutes ago, IIYAMA said: It looks fine, except for: (not sure if it is your typo) [ [ false, false, false, false, false, false, false, false, false, false ] ]se ] ] What happens if you debug: jsonData ? @majqq function onClientResourceStop() if fileExists("settings") then local settingsFile = fileOpen("settings") if settingsFile then local jsonData = toJSON(playerData.playerItems) outputDebugString(tostring(jsonData)) fileWrite(settingsFile, jsonData) fileClose(settingsFile) end end end addEventHandler("onClientResourceStop", getRootElement(), onClientResourceStop) Can't be my typo. File looks like i sent above. And settings file: [ [ false, false, false, false, false, false, false, false, false, false ] ]se ] ] Edited April 1, 2019 by majqq 1 Link to comment
Moderators IIYAMA Posted April 1, 2019 Moderators Share Posted April 1, 2019 (edited) @majqq That is a perfect result! (debug) But this will write too much JSON: 8 minutes ago, IIYAMA said: Oh and use resourceRoot for the even handler Edited April 1, 2019 by IIYAMA 1 1 Link to comment
Scripting Moderators ds1-e Posted April 1, 2019 Author Scripting Moderators Share Posted April 1, 2019 (edited) 5 minutes ago, IIYAMA said: @majqq That is a perfect result! But this will write too much JSON: Ah yes, i forget about that. But that isn't something wrong in the settings file? I mean how it looks inside, it's different from debug string. Edited April 1, 2019 by majqq 1 Link to comment
Moderators IIYAMA Posted April 1, 2019 Moderators Share Posted April 1, 2019 (edited) 13 minutes ago, majqq said: Ah yes, i forget about that. But that isn't something wrong in the settings file? Might be the reason for writing incomplete data. The file isn't flushed, so it might handy to do that as well: https://wiki.multitheftauto.com/wiki/FileFlush Oh and empty(recreate) the file each time you start writing data. @majqq The file is incorrect. There has been double written as you can see. (from a few moments before) se ] ] from: false, false ] ] Clean the file and try again. Edited April 1, 2019 by IIYAMA 1 Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now