|
Post by Pjot on Aug 11, 2019 11:13:26 GMT 1
All, Recently I have been looking into JSON structures and how these can be processed by BaCon. We can put a JSON structure into an associative array, because associative arrays allow multiple indexes separated by a comma. Take the following JSON string: { "item1" : "a", "object1" : { "item2" : "b", "item3" : 1 }, "object2" : "c" }
This should result into a DOM tree of item1, object1, object1.item2, object1.item3 and object2. For the associative arrays it would end up like this: json$("item1") --> has "a" json$("object1") --> has "{ "item2" : "b", "item3" : 1 }" json$("object1", "item2") --> has "b" json$("object1", "item3") --> has "1" json$("object2") --> has "c"
Obviously, all values in the associative array will be strings, even though JSON allows numbers and also 'true', 'false' and 'null' as native types. Nevertheless, parsing JSON now allows an easy query for the fields, in an recognizable hierarchical manner. A JSON structure also may contain arrays, these are automatically indexed with a zero-based numbering. For example: { "name":"John", "age":30, "cars": [ "Ford", "BMW", "Fiat" ]}
The result for this JSON structure will be the following: json$("name") --> has "John" json$("age") --> has "30" json$("cars") --> has "[ "Ford", "BMW", "Fiat" ]" json$("cars", "0") --> has "Ford" json$("cars", "1") --> has "BMW" json$("cars", "2") --> has "Fiat"
The code is here and demonstrates how it works. Basically, the Parse_JSON SUB will put the results into the associative array "json$()". The program prints the DOM tree of the string. BR Peter
|
|
|
Post by bigbass on Aug 11, 2019 18:34:41 GMT 1
Hello Peter interesting approach using bacon we could use an official json baconized parser for placing into an associative array and this looks clean as a command Btw here is another tool that parses json and was easy to figure out after a little testing I got this to work it was coded in c and is very light as a dependency Need to get 261 kB of archives. After this operation, 777 kB of additional disk space will be used. all the demos used curl but I just thought to echo -e 'some string' as input then pipe | jq and your DOT .filter hope it could be helpful also Joe stedolan.github.io/jq/jq 1.5 is in the official Debian and Ubuntu repositories. Install using sudo apt-get install jq #json$("item1") bacon equivalent echo -e '{ "item1" : "a", "object1" : { "item2" : "b", "item3" : 1 }, "object2" : "c" }' | jq '.item1' "a" #json$("object1") bacon equivalent echo -e '{ "item1" : "a", "object1" : { "item2" : "b", "item3" : 1 }, "object2" : "c" }' | jq '.object1' { "item2": "b", "item3": 1 } #json$("object1", "item2") bacon equivalent echo -e '{ "item1" : "a", "object1" : { "item2" : "b", "item3" : 1 }, "object2" : "c" }' | jq '.object1' | jq '.item2' "b" # json$("object1", "item3") bacon equivalent echo -e '{ "item1" : "a", "object1" : { "item2" : "b", "item3" : 1 }, "object2" : "c" }' | jq '.object1' | jq '.item3' 1 #json$("object2") bacon equivalentecho -e '{ "item1" : "a", "object1" : { "item2" : "b", "item3" : 1 }, "object2" : "c" }' | jq '.object2' "c"
|
|
|
Post by bigbass on Aug 11, 2019 21:47:03 GMT 1
just to be complete the second part equivalents
The jq documetaion could have been Writen with some simple examples More people would have used it
need to enclose the array number in square brackets '.[1]' when you filter
The bacon syntax is clearer to read And no added dependencies
#get name
echo -e '{ "name":"John", "age":30, "cars": [ "Ford", "BMW", "Fiat" ]}' | jq '.name' "John" #get age
echo -e '{ "name":"John", "age":30, "cars": [ "Ford", "BMW", "Fiat" ]}' | jq '.age' 30 #get cars echo -e '{ "name":"John", "age":30, "cars": [ "Ford", "BMW", "Fiat" ]}' | jq '.cars' [ "Ford", "BMW", "Fiat" ] # get the first index of cars
echo -e '{ "name":"John", "age":30, "cars": [ "Ford", "BMW", "Fiat" ]}' | jq '.cars' | jq '.[0]' "Ford" # get the second index of cars echo -e '{ "name":"John", "age":30, "cars": [ "Ford", "BMW", "Fiat" ]}' | jq '.cars' | jq '.[1]' "BMW" # get the third index of cars
echo -e '{ "name":"John", "age":30, "cars": [ "Ford", "BMW", "Fiat" ]}' | jq '.cars' | jq '.[2]' "Fiat"
#get the array length this is an extra bonus echo -e '{ "name":"John", "age":30, "cars": [ "Ford", "BMW", "Fiat" ]}' | jq 'length' 3
|
|
|
Post by vovchik on Aug 12, 2019 12:43:11 GMT 1
Dear Peter and Joe, Here are two small json parser libs (to be used as includes) that I found on github. I haven't yet tested them. With kind regards, vovchik Attachments:json.h-master.zip (60.75 KB)
parson-master.zip (28.18 KB)
|
|
|
Post by Pjot on Aug 12, 2019 20:45:57 GMT 1
Thanks guys, The 'jq' binary is interesting, I never knew this existed Before creating this parser I also looked at Github and other repos to see what JSON parsers are available. In the past, other forum users have used an external JSON library also (for example here) with various degrees of success. But the intention of the BaCon version is that I actually am considering to add JSON to ASSOC functionality native into BaCon. And then we need as less dependencies as possible. So my program was meant to be an investigation, or prototype, just to get an understanding of how such JSON parsing would work, and which pitfalls would be in the way. The BaCon version did not parse nested arrays correctly, but this now has been fixed (updated program here - refresh your browser cache if needed). Even though BaCon translates to C and uses optimized string processing, parsing 125 kilobyte of nested JSON arrays seems to be very slow. I will investigate how to speed up the parsing. As usual, feel free to share your thoughts or comments!
Best regards Peter EDIT: some minor improvements on the array numbering.
|
|
|
Post by Pjot on Aug 13, 2019 18:30:20 GMT 1
All, Attached some JSON examples which I used to test the algorithm. All examples and JSON snippets now are parsed correctly by the json2assoc program. BR Peter Attachments:json_examples.tar.gz (2.66 KB)
|
|
|
Post by bigbass on Aug 15, 2019 17:59:12 GMT 1
Hello Peter I am trying to get a better understanding of bacon's personalized way to do an associative array BTW this is my first try with bacon's associative array so I modified an example from here basic-converter.proboards.com/post/101/thread my example has error if I try to read string2$ at runtime but works doing the SPLIT string1$ works correctly I guess the [ ] brackets have something to do with it or I went about this the wrong way using SPLIT it reads in a file called json.cfg that only contains two lines for the demo to follow along with your given example strings json.string1={ "item1" : "a", "object1" : { "item2" : "b", "item3" : 1 }, "object2" : "c" } json.string2={ "name":"John", "age":30, "cars": [ "Ford", "BMW", "Fiat" ]}
DECLARE prop$ ASSOC STRING
configfile$ = "json.cfg"
OPEN configfile$ FOR READING AS fh WHILE NOT(ENDFILE(fh)) DO READLN txt$ FROM fh txt$ = CHOP$(txt$) IF NOT(ENDFILE(fh)) THEN l$ = LEFT$(txt$,INSTR(txt$,"=")-1) r$ = RIGHT$(txt$,LEN(txt$)-INSTR(txt$,"=")) prop$(l$) = r$ END IF WEND
'PRINT prop$("json.string1") 'PRINT prop$("json.string2") string2$= CONCAT$(prop$("json.string2")) string1$= CONCAT$(prop$("json.string1"))
LOCAL dimension SPLIT string1$ BY "," TO array$ SIZE dimension FOR i = 0 TO dimension filtered$= REPLACE$(array$[i], ":", "=") filtered$= REPLACE$(filtered$, "{", " ") filtered$= REPLACE$(filtered$, "}", " ") filtered$= REPLACE$(filtered$, "[", " ") filtered$= REPLACE$(filtered$, "]", " ") PRINT filtered$ & NL$ NEXT
terminal output"item1" = "a" "object1" = "item2" = "b" "item3" = 1 "object2" = "c"
|
|
|
Post by bigbass on Aug 16, 2019 6:08:39 GMT 1
dimension -1 fixed the runtime error took me awhile to solve that I added all of Peter's examples in one json.config file and they are all one line = strings the idea here is just some simplified demos for associative arrays and JSON to catch the idea of what is happening only I really just wanted to see some associative array examples for testing to document another only bacon basic example demo with no extra dependencies json-simple-parser.tar.gz (2.87 KB) Joe
|
|
|
Post by Pjot on Aug 16, 2019 8:21:08 GMT 1
Hi Joe, I expanded the chapter on associative arrays a little bit, hope it clarifies more. From C point of view, an associative array is nothing but a (generated) function which can take a variable amount of string arguments. Using this approach, the array is compilable by all C compilers. BR Peter
|
|
|
Post by alexfish on Aug 16, 2019 20:08:03 GMT 1
Hi Peter similar I think say he using ASSOC + RELATE '@ For Tree Types add extra at end to prevent recursive/lookup DECLARE TREE_MALE$ ,PARENT$, CHILD$,ANY$ ASSOC STRING
RELATE TREE_MALE$ TO PARENT$ RELATE TREE_MALE$ TO CHILD$ TREE_MALE$("Male Parent")="John" TREE_MALE$("John")="Mary" '@ Find The bits parent1$= PARENT$("Male Parent") kin$= CHILD$(parent1$)
PRINT " Male Parent ",parent1$," has a child called ",kin$ basic-converter.proboards.com/thread/647/associative-arrayBR Alex
|
|
|
Post by bigbass on Aug 17, 2019 6:34:42 GMT 1
Thanks Peter ,Alex and doyle for added info
It seems to me a small string can reference a large string of data and the configure file looks the easiest way to simplify what is happening
I was also interested porting some c++ with map to bacon now that we have that option also it may be possible to speed up the parsing with c++
I removed the using namespace std;
// CPP program to demonstrate associative arrays #include <bits/stdc++.h>
int main() { // the first data type i.e string represents // the type of key we want the second data type // i.e int represents the type of values we // want to store at that location std::map<std::string,std::string> values{ { "item1" , "a" }, { "item2", "b" }, { "item3", "1" }, { "item4", "c" } };
std::map<std::string, std::string>::iterator i; std::cout << "The values of all items are" << "\n"; for (i = values.begin(); i != values.end(); i++) std::cout << i->second << " ";
std::cout << "\n";
// the values of the items std::cout << "the value of item4 is" << " " << values["item4"] << "\n";
std::cout << "the value of item3 is " << values["item3"] << "\n"; }
Joe
|
|
|
Post by Pjot on Aug 22, 2019 18:34:59 GMT 1
All, This JSON parser really has been a PITA, but an interesting one After thorough testing with some random generated JSON strings, created by this wonderful website, I ran into several bugs which now also are fixed. Also I have changed the output format to a delimited string matrix, which consists of multiple lines each separated by a newline, and each line containing the JSON items separated by a single white space. The original quotes now are preserved so we can see if the item is a string, a number or an atom like null, true or false. The new JSON parser is here, it works for me with various kinds of JSON data, randomly nested and mixed with string data containing comma's or curly brackets. Also I was able to fix the performance issues which were caused by the LAST$/FIRST$ functions (fixed in the latest beta). At the same time, the JSON parser was setup to test the upcoming HASDELIM function, so please fetch the latest beta if you want to see the updated JSON parser working. Best regards Peter
|
|
|
Post by bigbass on Aug 23, 2019 5:17:11 GMT 1
Hello Peter
I am now getting the correct output from this latest parser using raspberry pi3 xubuntu 18.04
thanks for this parser its nice to have an all bacon parser
does this match your output results? if so all is well
side note : bacon fossil built correctly using clang
Joe
================================================== { "item1" : "a", "item2" : "b", "item3" : 1, "item4" : "2" } "item1" : "a" "item2" : "b" "item3" : 1 "item4" : "2" ================================================== { "item1" : "a", "object1" : { "item2" : "b", "item3" : 1, "item4" : "2" }, "object2" : "c" } "item1" : "a" " {"item2":"b","item3":1,"item4":"2"} "object1" "item2" "b" : " {"item2":"b","item3":1,"item4":"2"} "object1" "item2" "b" "object1" "item3" : 1 "object1" "item4" : "2" "object2" : "c" ================================================== { "name":"John","age":30,"cars":[ "Ford", "BMW", "Fiat" ]} "name" : "John" "age" : 30 " ["Ford","BMW","Fiat"] "cars" 0 "Ford" : " ["Ford","BMW","Fiat"] "cars" 0 "Ford" "cars" 1 : "BMW" "cars" 2 : "Fiat" ================================================== { "name":"John", "age":30,"cars": [{ "name":"Ford", "models": [ "Fiesta", "Focus", "Mustang" ] },{ "name":"BMW", "models": [ "320", "X3", "X5" ] },{ "name":"Fiat", "models": [ "500", "Panda" ] }]} "name" : "John" "age" : 30 a : [{"name":"Ford","models":["Fiesta","Focus","Mustang"]},{"name":"BMW","models":["320","X3","X5"]},{"name":"Fiat","models":["500","Panda"]}] "cars" 0 "name" : "Ford" a : ["Fiesta","Focus","Mustang"] "cars" 0 "models" 0 : "Fiesta" "cars" 0 "models" 1 : "Focus" "cars" 0 "models" 2 : "Mustang" "cars" 1 "name" : "BMW" " ["320","X3","X5"] "cars" 1 "models" 0 "320" : " ["320","X3","X5"] "cars" 1 "models" 0 "320" "cars" 1 "models" 1 : "X3" "cars" 1 "models" 2 : "X5" "cars" 2 "name" : "Fiat" a : ["500","Panda"] "cars" 2 "models" 0 : "500" "cars" 2 "models" 1 : "Panda" ================================================== {"menu": {"id": "file","value": "File","popup": {"menuitem": [{"value": "New", "onclick": "CreateNewDoc()"},{"value": "Open", "onclick": "OpenDoc()"},{"value": "Close", "onclick": "CloseDoc()"}]},"bla": "1"}} " {"id":"file","value":"File","popup":{"menuitem":[{"value":"New","onclick":"CreateNewDoc()"},{"value":"Open","onclick":"OpenDoc()"},{"value":"Close","onclick":"CloseDoc()"}]},"bla":"1"} "menu" "id" "file" : " {"id":"file","value":"File","popup":{"menuitem":[{"value":"New","onclick":"CreateNewDoc()"},{"value":"Open","onclick":"OpenDoc()"},{"value":"Close","onclick":"CloseDoc()"}]},"bla":"1"} "menu" "id" "file" "menu" "value" : "File" c : {"menuitem":[{"value":"New","onclick":"CreateNewDoc()"},{"value":"Open","onclick":"OpenDoc()"},{"value":"Close","onclick":"CloseDoc()"}]} e : [{"value":"New","onclick":"CreateNewDoc()"},{"value":"Open","onclick":"OpenDoc()"},{"value":"Close","onclick":"CloseDoc()"}] "menu" "popup" "menuitem" 0 "value" : "New" "menu" "popup" "menuitem" 0 "onclick" : "CreateNewDoc()" "menu" "popup" "menuitem" 1 "value" : "Open" "menu" "popup" "menuitem" 1 "onclick" : "OpenDoc()" "menu" "popup" "menuitem" 2 "value" : "Close" "menu" "popup" "menuitem" 2 "onclick" : "CloseDoc()" "menu" "bla" : "1"
------------------ (program exited with code: 0) Press return to continue
|
|
|
Post by Pjot on Aug 23, 2019 6:33:02 GMT 1
Thanks Joe,
I can see some output which doesn't look correct, below the expected output, when using GCC.
When compiling with CLang I get the same output as your post. So there seems to be a difference in GCC and CLang. I will try to find out why this is the case.
BR Peter
[peter@host ~]$ ./json2delim ================================================== { "item1" : "a", "item2" : "b", "item3" : 1, "item4" : "2" } "item1" : "a" "item2" : "b" "item3" : 1 "item4" : "2" ================================================== { "item1" : "a", "object1" : { "item2" : "b", "item3" : 1, "item4" : "2" }, "object2" : "c" } "item1" : "a" "object1" : {"item2":"b","item3":1,"item4":"2"} "object1" "item2" : "b" "object1" "item3" : 1 "object1" "item4" : "2" "object2" : "c" ================================================== { "name":"John","age":30,"cars":[ "Ford", "BMW", "Fiat" ]} "name" : "John" "age" : 30 "cars" : ["Ford","BMW","Fiat"] "cars" 0 : "Ford" "cars" 1 : "BMW" "cars" 2 : "Fiat" ================================================== { "name":"John", "age":30,"cars": [{ "name":"Ford", "models": [ "Fiesta", "Focus", "Mustang" ] },{ "name":"BMW", "models": [ "320", "X3", "X5" ] },{ "name":"Fiat", "models": [ "500", "Panda" ] }]} "name" : "John" "age" : 30 "cars" : [{"name":"Ford","models":["Fiesta","Focus","Mustang"]},{"name":"BMW","models":["320","X3","X5"]},{"name":"Fiat","models":["500","Panda"]}] "cars" 0 "name" : "Ford" "cars" 0 "models" : ["Fiesta","Focus","Mustang"] "cars" 0 "models" 0 : "Fiesta" "cars" 0 "models" 1 : "Focus" "cars" 0 "models" 2 : "Mustang" "cars" 1 "name" : "BMW" "cars" 1 "models" : ["320","X3","X5"] "cars" 1 "models" 0 : "320" "cars" 1 "models" 1 : "X3" "cars" 1 "models" 2 : "X5" "cars" 2 "name" : "Fiat" "cars" 2 "models" : ["500","Panda"] "cars" 2 "models" 0 : "500" "cars" 2 "models" 1 : "Panda" ================================================== {"menu": {"id": "file","value": "File","popup": {"menuitem": [{"value": "New", "onclick": "CreateNewDoc()"},{"value": "Open", "onclick": "OpenDoc()"},{"value": "Close", "onclick": "CloseDoc()"}]},"bla": "1"}} "menu" : {"id":"file","value":"File","popup":{"menuitem":[{"value":"New","onclick":"CreateNewDoc()"},{"value":"Open","onclick":"OpenDoc()"},{"value":"Close","onclick":"CloseDoc()"}]},"bla":"1"} "menu" "id" : "file" "menu" "value" : "File" "menu" "popup" : {"menuitem":[{"value":"New","onclick":"CreateNewDoc()"},{"value":"Open","onclick":"OpenDoc()"},{"value":"Close","onclick":"CloseDoc()"}]} "menu" "popup" "menuitem" : [{"value":"New","onclick":"CreateNewDoc()"},{"value":"Open","onclick":"OpenDoc()"},{"value":"Close","onclick":"CloseDoc()"}] "menu" "popup" "menuitem" 0 "value" : "New" "menu" "popup" "menuitem" 0 "onclick" : "CreateNewDoc()" "menu" "popup" "menuitem" 1 "value" : "Open" "menu" "popup" "menuitem" 1 "onclick" : "OpenDoc()" "menu" "popup" "menuitem" 2 "value" : "Close" "menu" "popup" "menuitem" 2 "onclick" : "CloseDoc()" "menu" "bla" : "1"
|
|
|
Post by bigbass on Aug 23, 2019 19:13:47 GMT 1
hello Peter
I would like to suggest a small thing if you could add a space after the comma or a space before the curly and square brackets of the demo example
for example this line I couldn't parse with SPLIT notice between },{ is the problem not having a space after the comma
{ "name":"John", "age":30,"cars": [{ "name":"Ford", "models": [ "Fiesta", "Focus", "Mustang" ] },{ "name":"BMW", "models": [ "320", "X3", "X5" ] },{ "name":"Fiat", "models": [ "500", "Panda" ] }]}
here is a working example demo remove the space between the }, { and it fails we are only interested in string13$ of the file json.config below
thanks any type of fix will be welcomed even if the SPLIT command needs to allow for },{
Joe
json.string1={"id": "0001","type": "donut","name": "Cake","ppu": 0.55,"batters":{"batter":[{ "id": "1001", "type": "Regular" },{ "id": "1002", "type": "Chocolate" },{ "id": "1003", "type": "Blueberry" },{ "id": "1004", "type": "Devil's Food" }]},"topping":[{ "id": "5001", "type": "None" },{ "id": "5002", "type": "Glazed" },{ "id": "5005", "type": "Sugar" },{ "id": "5007", "type": "Powdered Sugar" },{ "id": "5006", "type": "Chocolate with Sprinkles" },{ "id": "5003", "type": "Chocolate" },{ "id": "5004", "type": "Maple" }]} json.string2={ "quiz": { "sport": { "q1": { "question": "Which one is correct team name in NBA?", "options": [ "New York Bulls", "Los Angeles Kings", "Golden State Warriros", "Huston Rocket" ], "answer": "Huston Rocket" } }, "maths": { "q1": { "question": "5 + 7 = ?", "options": [ "10", "11", "12", "13" ], "answer": "12" }, "q2": { "question": "12 - 8 = ?", "options": [ "1", "2", "3", "4" ], "answer": "4" } } }} json.string3={ "squadName": "Super hero squad", "homeTown": "Metro City", "formed": 2016, "secretBase": "Super tower", "active": true, "members": [ { "name": "Molecule Man", "age": 29, "secretIdentity": "Dan Jukes", "powers": [ "Radiation resistance", "Turning tiny", "Radiation blast" ] }, { "name": "Madame Uppercut", "age": 39, "secretIdentity": "Jane Wilson", "powers": [ "Million tonne punch", "Damage resistance", "Superhuman reflexes" ] }, { "name": "Eternal Flame", "age": 1000000, "secretIdentity": "Unknown", "powers": [ "Immortality", "Heat Immunity", "Inferno", "Teleportation", "Interdimensional travel" ] } ]} json.string4={ "$id": "https://example.com/arrays.schema.json", "$schema": "http://json-schema.org/draft-07/schema#", "description": "A representation of a person, company, organization, or place", "type": "object", "properties": { "fruits": { "type": "array", "items": { "type": "string" } }, "vegetables": { "type": "array", "items": { "$ref": "#/definitions/veggie" } } }, "definitions": { "veggie": { "type": "object", "required": [ "veggieName", "veggieLike" ], "properties": { "veggieName": { "type": "string", "description": "The name of the vegetable." }, "veggieLike": { "type": "boolean", "description": "Do I like this vegetable?" } } } }} json.string5={ "array": [ 1, 2, 3 ], "boolean": true, "color": "#82b92c", "null": null, "number": 123, "object": { "a": "b", "c": "d", "e": "f" }, "string": "Hello World"} json.string6={"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[36.400834,38.265955],[36.40016,38.268742],[36.391272,38.280329],[36.376301,38.284649]]},"properties":{"f1":1,"f2":"Adana"}}]} json.string7={ "$schema": "http://json-schema.org/schema#", "title": "Product", "type": "object", "required": ["id", "name", "price"], "properties": { "id": { "type": "number", "description": "Product identifier" }, "name": { "type": "string", "description": "Name of the product" }, "price": { "type": "number", "minimum": 0 }, "tags": { "type": "array", "items": { "type": "string" } }, "stock": { "type": "object", "properties": { "warehouse": { "type": "number" }, "retail": { "type": "number" } } } }} json.string8={ "firstName": "John", "lastName": "Smith", "isAlive": true, "age": 27, "address": { "streetAddress": "21 2nd Street", "city": "New York", "state": "NY", "postalCode": "10021-3100" }, "phoneNumbers": [ { "type": "home", "number": "212 555-1234" }, { "type": "office", "number": "646 555-4567" }, { "type": "mobile", "number": "123 456-7890" } ], "children": [], "spouse": null} json.string9={ "book": [ { "id":"01", "language": "Java", "edition": "third", "author": "Herbert Schildt" }, { "id":"07", "language": "C++", "edition": "second", "author": "E.Balagurusamy" } ]} json.string10={ "collection" : { "version" : "1.0", "href" : "http://example.org/friends/", "links" : [ {"rel" : "feed", "href" : "http://example.org/friends/rss"} ], "items" : [ { "href" : "http://example.org/friends/jdoe", "data" : [ {"name" : "full-name", "value" : "J. Doe", "prompt" : "Full Name"}, {"name" : "email", "value" : "jdoe@example.org", "prompt" : "Email"} ], "links" : [ {"rel" : "blog", "href" : "http://examples.org/blogs/jdoe", "prompt" : "Blog"}, {"rel" : "avatar", "href" : "http://examples.org/images/jdoe", "prompt" : "Avatar", "render" : "image"} ] }, { "href" : "http://example.org/friends/msmith", "data" : [ {"name" : "full-name", "value" : "M. Smith", "prompt" : "Full Name"}, {"name" : "email", "value" : "msmith@example.org", "prompt" : "Email"} ], "links" : [ {"rel" : "blog", "href" : "http://examples.org/blogs/msmith", "prompt" : "Blog"}, {"rel" : "avatar", "href" : "http://examples.org/images/msmith", "prompt" : "Avatar", "render" : "image"} ] }, { "href" : "http://example.org/friends/rwilliams", "data" : [ {"name" : "full-name", "value" : "R. Williams", "prompt" : "Full Name"}, {"name" : "email", "value" : "rwilliams@example.org", "prompt" : "Email"} ], "links" : [ {"rel" : "blog", "href" : "http://examples.org/blogs/rwilliams", "prompt" : "Blog"}, {"rel" : "avatar", "href" : "http://examples.org/images/rwilliams", "prompt" : "Avatar", "render" : "image"} ] } ], "queries" : [ {"rel" : "search", "href" : "http://example.org/friends/search", "prompt" : "Search", "data" : [ {"name" : "search", "value" : ""} ] } ], "template" : { "data" : [ {"name" : "full-name", "value" : "", "prompt" : "Full Name"}, {"name" : "email", "value" : "", "prompt" : "Email"}, {"name" : "blog", "value" : "", "prompt" : "Blog"}, {"name" : "avatar", "value" : "", "prompt" : "Avatar"} ] } } } json.string11={ "collection" : { "version" : "1.0", "href" : "http://example.org/friends/", "links" : [ {"rel" : "feed", "href" : "http://example.org/friends/rss"}, {"rel" : "queries", "href" : "http://example.org/friends/?queries"}, {"rel" : "template", "href" : "http://example.org/friends/?template"} ], "items" : [ { "href" : "http://example.org/friends/jdoe", "data" : [ {"name" : "full-name", "value" : "J. Doe", "prompt" : "Full Name"}, {"name" : "email", "value" : "jdoe@example.org", "prompt" : "Email"} ], "links" : [ {"rel" : "blog", "href" : "http://examples.org/blogs/jdoe", "prompt" : "Blog"}, {"rel" : "avatar", "href" : "http://examples.org/images/jdoe", "prompt" : "Avatar", "render" : "image"} ] } ] } } json.string12={ "glossary": { "title": "example glossary", "GlossDiv": { "title": "S", "GlossList": { "GlossEntry": { "ID": "SGML", "SortAs": "SGML", "GlossTerm": "Standard Generalized Markup Language", "Acronym": "SGML", "Abbrev": "ISO 8879:1986", "GlossDef": { "para": "A meta-markup language, used to create markup languages such as DocBook.", "GlossSeeAlso": ["GML", "XML"] }, "GlossSee": "markup" } } } }} json.string13={ "name":"John", "age":30,"cars": [{ "name":"Ford", "models": [ "Fiesta", "Focus", "Mustang" ] }, { "name":"BMW", "models": [ "320", "X3", "X5" ] }, { "name":"Fiat", "models": [ "500", "Panda" ] }]}
simple-parser
DECLARE prop$ ASSOC STRING
configfile$ = "json.config"
OPEN configfile$ FOR READING AS fh WHILE NOT(ENDFILE(fh)) DO READLN txt$ FROM fh txt$ = CHOP$(txt$) IF NOT(ENDFILE(fh)) THEN l$ = LEFT$(txt$,INSTR(txt$,"=")-1) r$ = RIGHT$(txt$,LEN(txt$)-INSTR(txt$,"=")) prop$(l$) = r$ END IF WEND CLOSE FILE fh
'PRINT prop$("json.string1") 'PRINT prop$("json.string3") string1$= CONCAT$(prop$("json.string1")) string2$= CONCAT$(prop$("json.string2")) string3$= CONCAT$(prop$("json.string3")) string4$= CONCAT$(prop$("json.string4")) string5$= CONCAT$(prop$("json.string5")) string6$= CONCAT$(prop$("json.string6")) string7$= CONCAT$(prop$("json.string7")) string8$= CONCAT$(prop$("json.string8")) string9$= CONCAT$(prop$("json.string9")) string10$= CONCAT$(prop$("json.string10")) string11$= CONCAT$(prop$("json.string11")) string12$= CONCAT$(prop$("json.string12")) string13$= CONCAT$(prop$("json.string13"))
PRINT prop$("json.string13") '--- change the string number to test LOCAL dimension SPLIT string13$ BY "," TO array$ SIZE dimension FOR i = 0 TO dimension -1 filtered$= REPLACE$(array$[i], ":", "=") filtered$= REPLACE$(filtered$, "{", " ") filtered$= REPLACE$(filtered$, "}", " ") filtered$= REPLACE$(filtered$, "[", " ") filtered$= REPLACE$(filtered$, "]", " ") PRINT filtered$ & NL$ NEXT
|
|