JSON - load and dump arrays to/from JSON - AHK v1/2 - 2020/10/10 - a122

Share the finished AutoHotkey v2 Scripts and libraries you made here. Please put the current version of AutoHotkey v2 you used in Square Brackets at the start of the topic title.
User avatar
TheArkive
Posts: 405
Joined: 05 Aug 2016, 08:06
GitHub: TheArkive

JSON - load and dump arrays to/from JSON - AHK v1/2 - 2020/10/10 - a122

18 Apr 2020, 08:19

I found this script on GitHub thanks to user @Coco (if I'm not mistaken).

For AHK v2:
  • all quoted strings are properly detected regardless of contents (like numbers)
  • all linear arrays and maps are properly detected even when empty
  • unquoted numbers are output as unquoted on dump, and are properly read on load
This isn't as fancy as @HotKeyIt's Yaml and Json parser but it gets the job done.

===================================================================
Updates
===================================================================

Code: Select all

; AHK v2
; Example ===================================================================================
; ===========================================================================================

; a := Map(), b := Map(), c := Map(), d := Map(), e := Map(), f := Map() ; Object() is more technically correct than {} but both will work.

; d["g"] := 1, d["h"] := 2, d["i"] := ["purple","pink","pippy red"]
; e["g"] := 1, e["h"] := 2, e["i"] := Map("1","test1","2","test2","3","test3")
; f["g"] := 1, f["h"] := 2, f["i"] := [1,2,Map("a",1.0009,"b",2.0003,"c",3.0001)]

; a["test1"] := "test11", a["d"] := d
; b["test3"] := "test33", b["e"] := e
; c["test5"] := "test55", c["f"] := f

; myObj := Map()
; myObj["a"] := a, myObj["b"] := b, myObj["c"] := c, myObj["test7"] := "test77", myObj["test8"] := "test88"

; g := ["blue","green","red"], myObj["h"] := g ; add linear array for testing

; q := Chr(34)
; textData2 := Jxon_dump(myObj,4) ; ===> convert array to XML
; msgbox "XML Breakdown:`r`n===========================================`r`n(Should match second breakdown.)`r`n`r`n" textData2

; newObj := Jxon_load(textData2) ; ===> convert json back to array

; textData3 := Jxon_dump(newObj,4) ; ===> break down array into 2D layout again, should be identical
; msgbox "Second Breakdown:`r`n===========================================`r`n(should be identical to first breakdown)`r`n`r`n" textData3

; ExitApp

; ===========================================================================================
; End Example ; =============================================================================
; ===========================================================================================


; originally posted by user coco on AutoHotkey.com
; https://github.com/cocobelgica/AutoHotkey-JSON

Jxon_Load(ByRef src, args*) {
	static q := Chr(34)
	
	key := "", is_key := false
	stack := [ tree := [] ]
	is_arr := Map(tree, 1) ; ahk v2
	next := q "{[01234567890-tfn"
	pos := 0
	
	while ( (ch := SubStr(src, ++pos, 1)) != "" ) {
		if InStr(" `t`n`r", ch)
			continue
		if !InStr(next, ch, true) {
			testArr := StrSplit(SubStr(src, 1, pos), "`n")
			
			ln := testArr.Length
			col := pos - InStr(src, "`n",, -(StrLen(src)-pos+1))

			msg := Format("{}: line {} col {} (char {})"
			,   (next == "")      ? ["Extra data", ch := SubStr(src, pos)][1]
			  : (next == "'")     ? "Unterminated string starting at"
			  : (next == "\")     ? "Invalid \escape"
			  : (next == ":")     ? "Expecting ':' delimiter"
			  : (next == q)       ? "Expecting object key enclosed in double quotes"
			  : (next == q . "}") ? "Expecting object key enclosed in double quotes or object closing '}'"
			  : (next == ",}")    ? "Expecting ',' delimiter or object closing '}'"
			  : (next == ",]")    ? "Expecting ',' delimiter or array closing ']'"
			  : [ "Expecting JSON value(string, number, [true, false, null], object or array)"
			    , ch := SubStr(src, pos, (SubStr(src, pos)~="[\]\},\s]|$")-1) ][1]
			, ln, col, pos)

			throw Exception(msg, -1, ch)
		}
		
		obj := stack[1]
		memType := Type(obj)
		is_array := (memType = "Array") ? 1 : 0
		
		if i := InStr("{[", ch) { ; start new object / map?
			val := (i = 1) ? Map() : Array()	; ahk v2
			
			is_array ? obj.Push(val) : obj[key] := val
			stack.InsertAt(1,val)
			
			is_arr[val] := !(is_key := ch == "{")
			next := q (is_key ? "}" : "{[]0123456789-tfn")
		} else if InStr("}]", ch) {
			stack.RemoveAt(1)
			next := stack[1]==tree ? "" : is_arr[stack[1]] ? ",]" : ",}"
		} else if InStr(",:", ch) {
			is_key := (!is_array && ch == ",")
			next := is_key ? q : q "{[0123456789-tfn"
		} else { ; string | number | true | false | null
			if (ch == q) { ; string
				i := pos
				while i := InStr(src, q,, i+1) {
					val := StrReplace(SubStr(src, pos+1, i-pos-1), "\\", "\u005C")
					if (SubStr(val, -1) != "\")
						break
				}
				if !i ? (pos--, next := "'") : 0
					continue

				pos := i ; update pos

				val := StrReplace(val, "\/", "/")
				val := StrReplace(val, "\" . q, q)
				, val := StrReplace(val, "\b", "`b")
				, val := StrReplace(val, "\f", "`f")
				, val := StrReplace(val, "\n", "`n")
				, val := StrReplace(val, "\r", "`r")
				, val := StrReplace(val, "\t", "`t")

				i := 0
				while i := InStr(val, "\",, i+1) {
					if (SubStr(val, i+1, 1) != "u") ? (pos -= StrLen(SubStr(val, i)), next := "\") : 0
						continue 2

					xxxx := Abs("0x" . SubStr(val, i+2, 4)) ; \uXXXX - JSON unicode escape sequence
					if (xxxx < 0x100)
						val := SubStr(val, 1, i-1) . Chr(xxxx) . SubStr(val, i+6)
				}
				
				if is_key {
					key := val, next := ":"
					continue
				}
			} else { ; number | true | false | null
				val := SubStr(src, pos, i := RegExMatch(src, "[\]\},\s]|$",, pos)-pos)
				
                if IsInteger(val)
                    val += 0
                else if IsFloat(val)
                    val += 0
                else if (val == "true" || val == "false")
                    val := (val == "true")
                else if (val == "null")
                    val := ""
                else if is_key {			; Else if (pos--, next := "#")
                    pos--, next := "#"			; continue
                    continue
                }
				
				pos += i-1
			}
			
			is_array ? obj.Push(val) : obj[key] := val
			next := obj == tree ? "" : is_array ? ",]" : ",}"
		}
	}
	
	return tree[1]
}

Jxon_Dump(obj, indent:="", lvl:=1) {
	static q := Chr(34)
	
	if IsObject(obj) {
		memType := Type(obj) ; Type.Call(obj)
		is_array := (memType = "Array") ? 1 : 0
		
		if (memType ? (memType != "Object" And memType != "Map" And memType != "Array") : (ObjGetCapacity(obj) == ""))
			throw Exception("Object type not supported.", -1, Format("<Object at 0x{:p}>", ObjPtr(obj)))
		
		if IsInteger(indent)
		{
			if (indent < 0)
				throw Exception("Indent parameter must be a postive integer.", -1, indent)
			spaces := indent, indent := ""
			
			Loop spaces ; ===> changed
				indent .= " "
		}
		indt := ""
		
		Loop indent ? lvl : 0
			indt .= indent

		lvl += 1, out := "" ; Make #Warn happy
		for k, v in obj {
			if IsObject(k) || (k == "")
				throw Exception("Invalid object key.", -1, k ? Format("<Object at 0x{:p}>", ObjPtr(obj)) : "<blank>")
			
			; If (k = "")
				; Continue
			
			if !is_array ;// key ; ObjGetCapacity([k], 1)
				out .= (ObjGetCapacity([k]) ? Jxon_Dump(k) : q k q) (indent ? ": " : ":") ; token + padding
			
			out .= Jxon_Dump(v, indent, lvl) ; value
				.  ( indent ? ",`n" . indt : "," ) ; token + indent
		}

		if (out != "") {
			out := Trim(out, ",`n" . indent)
			if (indent != "")
				out := "`n" . indt . out . "`n" . SubStr(indt, StrLen(indent)+1)
		}
		
		return is_array ? "[" . out . "]" : "{" . out . "}"
	} else { ; Number
		number := "number"
		If (Type(obj) != "String")
			return obj
		Else {
			obj := StrReplace(obj,"`t","\t")
			obj := StrReplace(obj,"`r","\r")
			obj := StrReplace(obj,"`n","\n")
			obj := StrReplace(obj,"`b","\b")
			obj := StrReplace(obj,"`f","\f")
			obj := StrReplace(obj,"\","\\")
			obj := StrReplace(obj,"/","\/")
			obj := StrReplace(obj,q,"\" q)
			return q obj q
		}
	}
}
Last edited by TheArkive on 01 Dec 2020, 14:32, edited 20 times in total.
User avatar
TheArkive
Posts: 405
Joined: 05 Aug 2016, 08:06
GitHub: TheArkive

Re: YEJP - Yet Another Json Parser - Jxon (thanks coco!) - AHK v1 / v2

19 Apr 2020, 06:37

Issues in AHK v1:
  • all numbers are unquoted on dump, even if src data was quoted
  • on the bright side, numbers that start with zero are always quoted
  • empty arrays are detected as maps (how to detect obj type in AHK v1?)
    this shouldn't be an issue since you can add a ["key"] to a linear array, or populate an object with numerical keys in AHK v1
=================================================
Updates
=================================================

Code: Select all

; AHK v1
; Example ===================================================================================
; ===========================================================================================

; a := Object(), b := Object(), c := Object(), d := Object(), e := Object(), f := Object() ; Object() is more technically correct than {} but both will work.

; d["g"] := 1, d["h"] := 2, d["i"] := ["purple","pink","pippy red"]
; e["g"] := 1, e["h"] := 2, e["i"] := Object("1","test1","2","test2","3","test3")
; f["g"] := 1, f["h"] := 2, f["i"] := [1,2,Object("a",1.0009,"b",2.0003,"c",3.0001)]

; a["test1"] := "test11", a["d"] := d
; b["test3"] := "test33", b["e"] := e
; c["test5"] := "test55", c["f"] := f

; myObj := Object()
; myObj["a"] := a, myObj["b"] := b, myObj["c"] := c, myObj["test7"] := "test77", myObj["test8"] := "test88"

; g := ["blue","green","red"], myObj["h"] := g ; add linear array for testing

; q := Chr(34)
; textData2 := Jxon_dump(myObj,4) ; ===> convert array to XML
; msgbox % "XML Breakdown:`r`n===========================================`r`n(Should match second breakdown.)`r`n`r`n" textData2

; ===========================================================================================
; Error Test - Duplicate Node ; =============================================================
; ===========================================================================================
; textData2 := StrReplace(textData2,"</Base>","<test8 type=" q "String" q ">test88</test8>`r`n</Base>") ; <--- test error, duplicate node
; ===========================================================================================
; ===========================================================================================

; newObj := Jxon_load(textData2) ; ===> convert XML back to array

; textData3 := Jxon_dump(newObj,4) ; ===> break down array into 2D layout again, should be identical
; msgbox % "Second Breakdown:`r`n===========================================`r`n(should be identical to first breakdown)`r`n`r`n" textData3

; ExitApp

; ===========================================================================================
; End Example ; =============================================================================
; ===========================================================================================

; originally posted by user coco on AutoHotkey.com
; https://github.com/cocobelgica/AutoHotkey-JSON

Jxon_Load(ByRef src, args*) {
	static q := Chr(34)
	
	key := "", is_key := false
	stack := [ tree := [] ]
	is_arr := Object(tree, 1) ; ahk v1                    ; orig -> is_arr := { (tree): 1 }
	next := q "{[01234567890-tfn"
	pos := 0
	
	while ( (ch := SubStr(src, ++pos, 1)) != "" ) {
		if InStr(" `t`n`r", ch)
			continue
		if !InStr(next, ch, true) {
			testArr := StrSplit(SubStr(src, 1, pos), "`n")
			ln := testArr.Length()
			
			col := pos - InStr(src, "`n",, -(StrLen(src)-pos+1))

			msg := Format("{}: line {} col {} (char {})"
			,   (next == "")      ? ["Extra data", ch := SubStr(src, pos)][1]
			  : (next == "'")     ? "Unterminated string starting at"
			  : (next == "\")     ? "Invalid \escape"
			  : (next == ":")     ? "Expecting ':' delimiter"
			  : (next == q)       ? "Expecting object key enclosed in double quotes"
			  : (next == q . "}") ? "Expecting object key enclosed in double quotes or object closing '}'"
			  : (next == ",}")    ? "Expecting ',' delimiter or object closing '}'"
			  : (next == ",]")    ? "Expecting ',' delimiter or array closing ']'"
			  : [ "Expecting JSON value(string, number, [true, false, null], object or array)"
			    , ch := SubStr(src, pos, (SubStr(src, pos)~="[\]\},\s]|$")-1) ][1]
			, ln, col, pos)

			throw Exception(msg, -1, ch)
		}
		
		is_array := is_arr[obj := stack[1]] 
		
		if i := InStr("{[", ch) { ; start new object / map?
			val := (i = 1) ? Object() : Array()	; ahk v1
			
			is_array ? obj.Push(val) : obj[key] := val
			stack.InsertAt(1,val)
			
			is_arr[val] := !(is_key := ch == "{")
			next := q (is_key ? "}" : "{[]0123456789-tfn")
		} else if InStr("}]", ch) {
			stack.RemoveAt(1)
			next := stack[1]==tree ? "" : is_arr[stack[1]] ? ",]" : ",}"
		} else if InStr(",:", ch) {
			is_key := (!is_array && ch == ",")
			next := is_key ? q : q "{[0123456789-tfn"
		} else { ; string | number | true | false | null
			if (ch == q) { ; string
				i := pos
				while i := InStr(src, q,, i+1) {
					val := StrReplace(SubStr(src, pos+1, i-pos-1), "\\", "\u005C")
					if (SubStr(val, 0) != "\")
						break
				}
				if !i ? (pos--, next := "'") : 0
					continue

				pos := i ; update pos

				  val := StrReplace(val,    "\/",  "/")
				val := StrReplace(val, "\" . q,    q)
				, val := StrReplace(val,    "\b", "`b")
				, val := StrReplace(val,    "\f", "`f")
				, val := StrReplace(val,    "\n", "`n")
				, val := StrReplace(val,    "\r", "`r")
				, val := StrReplace(val,    "\t", "`t")

				i := 0
				while i := InStr(val, "\",, i+1) {
					if (SubStr(val, i+1, 1) != "u") ? (pos -= StrLen(SubStr(val, i)), next := "\") : 0
						continue 2

					xxxx := Abs("0x" . SubStr(val, i+2, 4)) ; \uXXXX - JSON unicode escape sequence
					if (A_IsUnicode || xxxx < 0x100)
						val := SubStr(val, 1, i-1) . Chr(xxxx) . SubStr(val, i+6)
				}
				
				if is_key {
					key := val, next := ":"
					continue
				}
			} else { ; number | true | false | null
				val := SubStr(src, pos, i := RegExMatch(src, "[\]\},\s]|$",, pos)-pos)
				
				static number := "number", integer := "integer", float := "float"
				if val is %number%
				{
					if val is %integer%
						val += 0
					if val is %float%
						val += 0
					else if (val == "true" || val == "false")
						val := (val == "true")
					else if (val == "null")
						val := ""
					else if is_key {					; else if (pos--, next := "#")
						pos--, next := "#"					; continue
						continue
					}
				}
				
				pos += i-1
			}
			
			is_array ? obj.Push(val) : obj[key] := val
			next := obj == tree ? "" : is_array ? ",]" : ",}"
		}
	}
	
	return tree[1]
}

Jxon_Dump(obj, indent:="", lvl:=1) {
	static q := Chr(34), chunkType := ""
	
	if IsObject(obj) {
		is_array := 0
		for k in obj
			is_array := k == A_Index
		until !is_array
		memType := is_array ? "Array" : "Map"
		
		if (memType ? (memType != "Object" And memType != "Map" And memType != "Array") : (ObjGetCapacity(obj) == ""))
			throw Exception("Object type not supported.", -1, Format("<Object at 0x{:p}>", &obj))
		
		static integer := "integer"
		if indent is integer ; %integer%
		{
			if (indent < 0)
				throw Exception("Indent parameter must be a postive integer.", -1, indent)
			spaces := indent, indent := ""
			If (A_AhkVersion < 2) {
				Loop %spaces% ; ===> changed
					indent .= " "
			} Else {
				Loop spaces ; ===> changed
					indent .= " "
			}
		}
		indt := ""
		lpCount := indent ? lvl : 0
		Loop %lpCount%
			indt .= indent

		lvl += 1, out := "" ; Make #Warn happy
		for k, v in obj {
			if IsObject(k) || (k == "")
				throw Exception("Invalid object key.", -1, k ? Format("<Object at 0x{:p}>", &obj) : "<blank>")
			
			if !is_array ;// key ; ObjGetCapacity([k], 1)
				chunkType := "key", out .= (ObjGetCapacity([k]) ? Jxon_Dump(k) : q k q) (indent ? ": " : ":") ; token + padding
			
            chunkType := "value" ; need to check when calling Jxon_Dump() internally, if chunkType is a key or value
			out .= Jxon_Dump(v, indent, lvl) ; value
				.  ( indent ? ",`n" . indt : "," ) ; token + indent
		}

		if (out != "") {
			out := Trim(out, ",`n" . indent)
			if (indent != "")
				out := "`n" . indt . out . "`n" . SubStr(indt, StrLen(indent)+1)
		}
		
		return is_array ? "[" . out . "]" : "{" . out . "}"
	} else { ; Number
		copyObj := obj + 0
        If (copyObj = obj And chunkType != "key")
			return obj
		Else {
			obj := StrReplace(obj,"`t","\t")
			obj := StrReplace(obj,"`r","\r")
			obj := StrReplace(obj,"`n","\n")
			obj := StrReplace(obj,"`b","\b")
			obj := StrReplace(obj,"`f","\f")
			obj := StrReplace(obj,"\","\\")
			obj := StrReplace(obj,"/","\/")
			obj := StrReplace(obj,q,"\" q)
			return q obj q
		}
	}
}
Last edited by TheArkive on 01 Dec 2020, 07:12, edited 6 times in total.
User avatar
TheArkive
Posts: 405
Joined: 05 Aug 2016, 08:06
GitHub: TheArkive

Re: YEJP - Yet Another Json Parser - Jxon - AHK v1/2 - 2020/06/20

20 Jun 2020, 15:04

Latest Update: 2020/07/09

Updated AHK v1 / v2 JXON for escaped /. It was commented out (can't remember why). User @Tigerlily caught this and reported it.
Last edited by TheArkive on 09 Jul 2020, 01:07, edited 1 time in total.
User avatar
Tigerlily
Posts: 360
Joined: 04 Oct 2018, 22:31

Re: YEJP - Yet Another Json Parser - AHK v1/2 - 2020/07/01 - a113

08 Jul 2020, 19:16

@TheArkive
Thank you for posting this. I'm running into an issue with the first string i tried to parse, can you let me know what I'm doing wrong?

code:

Code: Select all

word := "wonderful"

/*
{
    "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 := FileRead( A_ScriptDir "\dictionary_" word ".txt" )

wordInfo := Jxon_Load( json )

MsgBox wordInfo["glossary", "title"]
error:
Image
-TL
User avatar
kczx3
Posts: 1223
Joined: 06 Oct 2015, 21:39

Re: YEJP - Yet Another Json Parser - AHK v1/2 - 2020/07/01 - a113

08 Jul 2020, 20:42

Separate out your keys to both be in brackets. Or just use dot notation.
User avatar
Tigerlily
Posts: 360
Joined: 04 Oct 2018, 22:31

Re: YEJP - Yet Another Json Parser - AHK v1/2 - 2020/07/01 - a113

08 Jul 2020, 23:52

kczx3 wrote:
08 Jul 2020, 20:42
Separate out your keys to both be in brackets. Or just use dot notation.
I tried dot notation and receive this error:

Image

However, for some reason bracket notation worked fine so I'll stick with that for now.. although dot notation would be a little less typing :think:
-TL
User avatar
TheArkive
Posts: 405
Joined: 05 Aug 2016, 08:06
GitHub: TheArkive

Re: YEJP - Yet Another Json Parser - AHK v1/2 - 2020/07/01 - a113

09 Jul 2020, 00:14

In AHK v1, keys vs dot notation is interchangable. In AHK v2 it isn't. So if you are working with a map you need obj["key"] notation.

Did ya get it working ok?
User avatar
Tigerlily
Posts: 360
Joined: 04 Oct 2018, 22:31

Re: YEJP - Yet Another Json Parser - AHK v1/2 - 2020/07/01 - a113

09 Jul 2020, 00:22

I'm receiving this string from the Merriam Webster dictionary:

Code: Select all

{"meta":{"id":"wonderful","uuid":"70456b1b-72ae-43ed-85cd-3e19ccf4b864","sort":"230207100","src":"collegiate","section":"alpha","stems":["wonderful","wonderfuller","wonderfullest","wonderfully","wonderfulness","wonderfulnesses"],"offensive":false},"hwi":{"hw":"won*der*ful","prs":[{"mw":"\u02c8w\u0259n-d\u0259r-f\u0259l","sound":{"audio":"wonder03","ref":"c","stat":"1"}}]},"fl":"adjective","def":[{"sseq":[[["sense",{"sn":"1","dt":[["text","{bc}exciting {a_link|wonder} {bc}{sx|marvelous||}, {sx|astonishing||} "],["vis",[{"t":"a sight {wi}wonderful{\/wi} to behold"}]]]}]],[["sense",{"sn":"2","dt":[["text","{bc}unusually good {bc}{sx|admirable||} "],["vis",[{"t":"did a {wi}wonderful{\/wi} job"}]]]}]]]}],"uros":[{"ure":"won*der*ful*ly","prs":[{"mw":"\u02c8w\u0259n-d\u0259r-f(\u0259-)l\u0113","sound":{"audio":"wonder04","ref":"c","stat":"1"}}],"fl":"adverb"},{"ure":"won*der*ful*ness","prs":[{"mw":"\u02c8w\u0259n-d\u0259r-f\u0259l-n\u0259s","sound":{"audio":"wonder05","ref":"c","stat":"1"}}],"fl":"noun"}],"date":"before 12th century{ds||1||}","shortdef":["exciting wonder : marvelous, astonishing","unusually good : admirable"]}
beautified:

Code: Select all

{
	"meta": {
		"id": "wonderful",
		"uuid": "70456b1b-72ae-43ed-85cd-3e19ccf4b864",
		"sort": "230207100",
		"src": "collegiate",
		"section": "alpha",
		"stems": ["wonderful", "wonderfuller", "wonderfullest", "wonderfully", "wonderfulness", "wonderfulnesses"],
		"offensive": false
	},
	"hwi": {
		"hw": "won*der*ful",
		"prs": [{
			"mw": "\u02c8w\u0259n-d\u0259r-f\u0259l",
			"sound": {
				"audio": "wonder03",
				"ref": "c",
				"stat": "1"
			}
		}]
	},
	"fl": "adjective",
	"def": [{
		"sseq": [
			[
				["sense", {
					"sn": "1",
					"dt": [
						["text", "{bc}exciting {a_link|wonder} {bc}{sx|marvelous||}, {sx|astonishing||} "],
						["vis", [{
							"t": "a sight {wi}wonderful{\/wi} to behold"
						}]]
					]
				}]
			],
			[
				["sense", {
					"sn": "2",
					"dt": [
						["text", "{bc}unusually good {bc}{sx|admirable||} "],
						["vis", [{
							"t": "did a {wi}wonderful{\/wi} job"
						}]]
					]
				}]
			]
		]
	}],
	"uros": [{
		"ure": "won*der*ful*ly",
		"prs": [{
			"mw": "\u02c8w\u0259n-d\u0259r-f(\u0259-)l\u0113",
			"sound": {
				"audio": "wonder04",
				"ref": "c",
				"stat": "1"
			}
		}],
		"fl": "adverb"
	}, {
		"ure": "won*der*ful*ness",
		"prs": [{
			"mw": "\u02c8w\u0259n-d\u0259r-f\u0259l-n\u0259s",
			"sound": {
				"audio": "wonder05",
				"ref": "c",
				"stat": "1"
			}
		}],
		"fl": "noun"
	}],
	"date": "before 12th century{ds||1||}",
	"shortdef": ["exciting wonder : marvelous, astonishing", "unusually good : admirable"]
}

I am receiving an error using this code:

Code: Select all

word := "wonderful"
Download( "https://www.dictionaryapi.com/api/v3/references/collegiate/json/" word "?key=YOUR-API-KEY", A_ScriptDir "\dictionary_" word ".txt" )
json := FileRead( A_ScriptDir "\dictionary_" word ".txt" )
json := Trim( json, "[]" ) ; for some reason the returned string comes with a set of square brackets encasing the JSON object
wordInfo := Jxon_Load( json )
MsgBox wordInfo["meta"]["id"]
error:
Image

the culprit:

Code: Select all

							"t": "a sight {wi}wonderful{\/wi} to behold"
						}]]
					]
				}]
			],
			[
				["sense", {
					"sn": "2",
					"dt": [
						["text", "{bc}unusually good {bc}{sx|admirable||} "],
						["vis", [{
							"t": "did a {wi}wonderful{\/wi} job"
when I remove the two \/ everything seems to work fine. I checked and the string is valid JSON, is this the APIs string causing this issue?
Last edited by Tigerlily on 09 Jul 2020, 00:24, edited 1 time in total.
-TL
User avatar
Tigerlily
Posts: 360
Joined: 04 Oct 2018, 22:31

Re: YEJP - Yet Another Json Parser - AHK v1/2 - 2020/07/01 - a113

09 Jul 2020, 00:23

@TheArkive
thanks for the heads up, that makes sense why the dot notation isn't working.

i got it working with a very simple json example string, however, now after trying to pull string from an API, getting the above issue.
-TL
User avatar
TheArkive
Posts: 405
Joined: 05 Aug 2016, 08:06
GitHub: TheArkive

Re: YEJP - Yet Another Json Parser - AHK v1/2 - 2020/07/01 - a113

09 Jul 2020, 00:37

Try NOT trimming the brackets.

the Brackets represent a linear array []. Curly braces {} represent a map (or associative array). The top level of the json element will have one of these always. That's how objects are saved / layered. By removing this, you are actually breaking it.

Let me know what happens when you don't trim the braces.
User avatar
TheArkive
Posts: 405
Joined: 05 Aug 2016, 08:06
GitHub: TheArkive

Re: YEJP - Yet Another Json Parser - AHK v1/2 - 2020/07/01 - a113

09 Jul 2020, 00:44

Oh i see ... top level is [] ... and it still has {} as the next level down? that's a little excessive ;P ... ok i'm trying to load this up and see what i see

EDIT: i got it to load. Gotta re-add the escape for /. Should be around line 71 ish:

val := StrReplace(val, "\/", "/")

uncomment this line and try again.

EDIT: It's working... return value was "wonderful" as expected.

EDIT: Just to be extra sure more errors wouldn't pop up, it's double confirmed it was the escape for / ... so where you see \/ was causing it. I had that line that did that replacement commented out, not sure why. But thanks for reporting! I'll fix this in the OP.
User avatar
Tigerlily
Posts: 360
Joined: 04 Oct 2018, 22:31

Re: YEJP - Yet Another Json Parser - AHK v1/2 - 2020/07/01 - a115

09 Jul 2020, 20:41

@TheArkive
Thanks, you rock!

Really appreciate you updating this lib for a115!!!!! :bravo:
-TL
User avatar
TheArkive
Posts: 405
Joined: 05 Aug 2016, 08:06
GitHub: TheArkive

Re: YEJP - Yet Another Json Parser - AHK v1/2 - 2020/07/31 - a121

10 Oct 2020, 13:52

Update 2020/10/10 - for AHK v1 version (post #2)
  • Fixed an error when trying to load arrays. Updated Jxon_dump(), now it properly quotes keys that are numerical values in Object() arrays. Unquoted keys were the cause of the error.
JoeSchmoe
Posts: 52
Joined: 08 Dec 2014, 08:58

Re: JSON - load and dump arrays to/from JSON - AHK v1/2 - 2020/10/10 - a122

31 Oct 2020, 21:17

Hey, man, I just wanted to thank you for updating this. Good stuff, and much needed. :bravo:
User avatar
TheArkive
Posts: 405
Joined: 05 Aug 2016, 08:06
GitHub: TheArkive

Re: JSON - load and dump arrays to/from JSON - AHK v1/2 - 2020/10/10 - a122

01 Nov 2020, 04:50

@JoeSchmoe
Glad you are able to make use of this :D
Curdflappers
Posts: 4
Joined: 13 Nov 2020, 03:18
GitHub: markwiemer

Re: JSON - load and dump arrays to/from JSON - AHK v1/2 - 2020/10/10 - a122

14 Nov 2020, 03:19

@TheArkive Thanks so much! I've been working on converting this for a few days, but I'm very new to AHK syntax. I'm working on this script on GitHub, do you mind if I incorporate your changes to my repo, crediting you, of course?
User avatar
TheArkive
Posts: 405
Joined: 05 Aug 2016, 08:06
GitHub: TheArkive

Re: JSON - load and dump arrays to/from JSON - AHK v1/2 - 2020/10/10 - a122

14 Nov 2020, 05:05

@Curdflappers
Sure man, no problem. What exactly are you trying to convert? I have both AHK v1 and v2 scripts posted in this thread. AHK v1 version is in post #2.
Curdflappers
Posts: 4
Joined: 13 Nov 2020, 03:18
GitHub: markwiemer

Re: JSON - load and dump arrays to/from JSON - AHK v1/2 - 2020/10/10 - a122

14 Nov 2020, 05:23

@TheArkive: I'm working on updating Chrome.ahk by G33kDude, which allows AHK scripts to navigate Chromium browsers like Google Chrome and Microsoft Edge. It logs through an old JSON-parsing library originally written by cocobelgica. In order to update Chrome.ahk, I need to update the JSON-parsing library. :)
User avatar
TheArkive
Posts: 405
Joined: 05 Aug 2016, 08:06
GitHub: TheArkive

Re: JSON - load and dump arrays to/from JSON - AHK v1/2 - 2020/10/10 - a122

14 Nov 2020, 17:17

@Curdflappers
Look at the 2nd post in this thread. My library is actually already converted from cocobelgica (see 1st post, 1st link). Just don't want you to spend unnecessary time if ya don't have to.

Post #1 is for AHK v2
Post #2 is for AHK v1

Hopefully you can just copy-paste for whatever version of AHK you are writing / converting Chrome.ahk for.
Last edited by TheArkive on 15 Nov 2020, 05:26, edited 1 time in total.
Curdflappers
Posts: 4
Joined: 13 Nov 2020, 03:18
GitHub: markwiemer

Re: JSON - load and dump arrays to/from JSON - AHK v1/2 - 2020/10/10 - a122

15 Nov 2020, 01:15

Yeah, you're right, I didn't think my response through. I'm working on updating a fork of Coco (and G33kDude)'s repository, so I wanted to verify that this was OK to publish on my account. I'll give you credit in the script, of course!

Return to “AutoHotkey v2 Scripts and Functions”

Who is online

Users browsing this forum: No registered users and 1 guest