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

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: 330
Joined: 05 Aug 2016, 08:06
GitHub: TheArkive

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

Post by TheArkive » 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 IsNumber(val) {
					if IsInteger(val)
						val += 0
					else if IsFloat(val)
						val += 0
					else if (val == "true" || val == "false")
						val := %val% + 0
					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 11 Aug 2020, 15:21, edited 14 times in total.

User avatar
TheArkive
Posts: 330
Joined: 05 Aug 2016, 08:06
GitHub: TheArkive

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

Post by TheArkive » 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% + 0
					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) {
		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)
				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
		copyObj := obj + 0
		If (copyObj = obj And InStr(obj,0) != 1)
			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 19 Jul 2020, 02:16, edited 3 times in total.

User avatar
TheArkive
Posts: 330
Joined: 05 Aug 2016, 08:06
GitHub: TheArkive

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

Post by TheArkive » 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: 353
Joined: 04 Oct 2018, 22:31

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

Post by Tigerlily » 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: 1140
Joined: 06 Oct 2015, 21:39

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

Post by kczx3 » 08 Jul 2020, 20:42

Separate out your keys to both be in brackets. Or just use dot notation.

User avatar
Tigerlily
Posts: 353
Joined: 04 Oct 2018, 22:31

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

Post by Tigerlily » 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: 330
Joined: 05 Aug 2016, 08:06
GitHub: TheArkive

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

Post by TheArkive » 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: 353
Joined: 04 Oct 2018, 22:31

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

Post by Tigerlily » 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: 353
Joined: 04 Oct 2018, 22:31

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

Post by Tigerlily » 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: 330
Joined: 05 Aug 2016, 08:06
GitHub: TheArkive

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

Post by TheArkive » 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: 330
Joined: 05 Aug 2016, 08:06
GitHub: TheArkive

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

Post by TheArkive » 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: 353
Joined: 04 Oct 2018, 22:31

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

Post by Tigerlily » 09 Jul 2020, 20:41

@TheArkive
Thanks, you rock!

Really appreciate you updating this lib for a115!!!!! :bravo:
-TL

Post Reply

Return to “AutoHotkey v2 Scripts and Functions”