If would be nice to be able to use this to do one test of a json key, to see whether it exists and is for example a @jsonObj.
I don't suppose it is possible to have a return value of -1 to say that the key is undefined rather than a crash.
Thank you. I have, previously, made a similar request. My request is that one be able to define a default value that is returned if the key doesn't exist. I currently use this but would MUCH PREFER the default option as I generally just want the field to be blank if it doesn't exist without having to check anything but one could, obviously, put anything such as -1.
Appreciate the request. Maybe it will help.
Jim
:WBERRORHANDLER
If StrTrim(ItemExtract(1,wberrortextstring,":")) == 20108 Then
%wberroradditionalinfo% = ""
EndIf
IntControl(73, 2, @TRUE, 1, 0)
Return
I think I was on the agree list with a default value for jsValueGet. It just makes sense.
And while we are talking about our wishlists, maybe a try/catch mechanism?
Tony has already re-phrased that the Extender has a KeyExists() function, that searches and counts for the entire file. So assuming a json array of values, where in some blocks a value is missing for a certain key, but it exists in other blocks. So in iterating block by block, there are times the jsvalue for that key does not exist. But, for processing to outcome you would like to have those keys a default value. Why suggest -1 which is a true boolean, and not 0 to suggest false or key does not exist in this block? As for try/catch I would only use that to determine if json was valid in the first place. Or, I am missing something here.
[EDIT]
I am, of course, talking about json data that is orthogonal. Otherwise, I assume it is just a mocked-up structure.
https://docs.winbatch.com/mergedProjects/Json/jsKeyExist.htm (https://docs.winbatch.com/mergedProjects/Json/jsKeyExist.htm)
Am aware of jsKeyExist. I find that I am spending all my time checking if the key exists and whether it has a value or a null. And it's just a request.
If you also want to put try/catch on your list of things to do, that would be nice also. Would make my job a hell of a lot easier.
Quote from: bottomleypotts on July 03, 2025, 06:22:22 AMIf you also want to put try/catch on your list of things to do, that would be nice also. Would make my job a hell of a lot easier.
A bit of a long thread, but try/catch was discussed here and Tony mentions a WB alternative.
https://forum.winbatch.com/index.php?topic=2949.msg17069#msg17069
Adding a JSON data type for key values that do not exist is an interesting idea.
Quote from: td on July 04, 2025, 09:28:49 AMAdding a JSON data type for key values that do not exist is an interesting idea.
and with all due respect to the OP and Jim (via separate discussion)
- key exists but missing in certain array blocks
- key does not exist in any part of json
- key does not exist but needs to be created and filled
- key is supposed to exist but somehow it doesn't
and the return should either be @true or @false [in my .02 opinion]
Have worked with all these scenarios in the last ten years. Actually found XML as better parsing format. But all that aside, Json gets a lot of hype and if you are dealing with it on a regular basis, be prepared to write error handling and specific processing udf's.
Doesn't mean jsValueGet() could not return either a value or a reason.
Good summary but forgive my ignorance. What should return a @true or @false? jsValueGet? I suppose a new function could be added that performs the get operation and returns @true or @false. The value would need to be returned as a will function pointer.
Pseudo code.
if jsValueGetEx(somecontainer, 'somekey', ".", &value)
;Process value
Currently, it looks like
if jsKeyExist(somecontainer, 'somekey', ".", &Path)
value = jsValueGetEx(somecontainer, Paths[0], ".")
;Process value
To me, it is just extending jsExistKey to return an undefined. Undefined can be @false, where if it exists it can continue as it does. I used -1 in my OP only as an example.
I dont require the value returned as a pointer because if the value exists then I use it as normal from json.
And while we are chatting, can someone tell me why a @jsonNull type would return the string 'null' when I retrieve its value?
Quote from: td on July 04, 2025, 12:52:22 PMGood summary but forgive my ignorance. What should return a @true or @false? jsValueGet?
My bad. I am working on a function jdescribe(jsonfile) building a tabular output:
key keytype keycount
=== ======= ========
where true/false returns are based on interpreting the output. In testing worked nice on small orthogonal json files, but for larger unstructured files seems to require a fileread() with line by interpretation. Also found that if a key name begins with a numeric parsing will error unless it is single quoted.
Probably get accused of hi-jacking the thread, but to follow up on attempts to 'describe' a json file I'm at an initial point... I posted Json I created for WB 64bit dll properties a few threads ago. It is nested... i.e. [sample]
{
"WB 64-bit": {
"Winbatch DLL": [
[
{
"DLL_Name": "ilcfs64i.dll",
"Size[KB]": 940,
"Loaded": "7/19/2024 5:49:45 AM",
"LastWriteTime": "7/17/2024 1:57:40 PM",
"Version": {
"Comments": "",
"CompanyName": "Island Lake Consulting LLC",
"FileBuildPart": 0,
"FileDescription": "WIL Extender",
"FileMajorPart": 44001,
"FileMinorPart": 0,
"FileName": "C:\\Program Files\\WinBatch\\System\\ilcfs64i.dll",
"FilePrivatePart": 0,
"FileVersion": "44001",
"InternalName": "ilfslxxi.dll",
"IsDebug": false,
"IsPatched": false,
"IsPrivateBuild": false,
"IsPreRelease": false,
"IsSpecialBuild": false,
"Language": "English (United States)",
"LegalCopyright": "Copyright (C) 2023-2024 Island Lake Consulting LLC",
"LegalTrademarks": "",
"OriginalFilename": "ilfslxxi.dll",
"PrivateBuild": "",
"ProductBuildPart": 0,
"ProductMajorPart": 44001,
"ProductMinorPart": 0,
"ProductName": "WIL FTPs Extender",
"ProductPrivatePart": 0,
"ProductVersion": "44001",
"SpecialBuild": "",
"FileVersionRaw": {
"Major": 44001,
"Minor": 0,
"Build": 0,
I can account for the entries path and values [see attached]. The output is .csv so would easily go into Excel, but looking to create functions to determine Number of Array items (if an array), Naming convention (if sent to dataset)... Working on getting data types and missing values. Expect feedback that it is a lot of work or needless replication. Json is not easy and there is no one shoe fits all. But I would like to think of this board as collaborative, with code and samples, not just complaints.
Quote from: bottomleypotts on July 05, 2025, 12:19:57 AMAnd while we are chatting, can someone tell me why a @jsonNull type would return the string 'null' when I retrieve its value?
Null is a
JSON type that uses the word "null" as its value. Null is a special symbol in JSON and is not the same thing as "Null" in quotes. The extender makes the distinction by reporting the data type when queried.
AddExtender(`ilcjs44i.dll`,0,`ilcjs64i.dll`) ; Load the JSON extender
json = '{ "a": null, "b": "null" }'
j = jsParse(json)
theValue = jsValueGet(j,`[a]`) ; string_unicode of "null"
theType = jsValueType(j,`[a]`) ; 1 = @jsonNull
Exit
I'm well aware of how json works. I don't get how you don't see the confusion nor the hastle of coding with json here.
Stan, you're the king of coming into peoples threads and killing any discussion.
#DefineFunction JSON(strJSONData, strJSONKey) ; udfGetJSONValue
If strJSONData==`` Then Return ``
o=CreateObject(`MSScriptControl.ScriptControl`)
o.Language=`JScript`
Rc=ErrorMode(@OFF)
Ret=o.Eval(:`var obj=`:strJSONData:`;obj`:strJSONKey)
ErrorMode(Rc)
Return StrCat(Ret)
#EndFunction
fn=DirScript():"WB64.json"
j=FileGet(fn)
n=json(j,'["WB 64-bit"]["Winbatch DLL"][0].length') ; 22
Exit
And yet, here you are asking for the same help that you personally have shut down on me on several occassions. Let me know if you want links.
Nope, too easy. What you're asking for is EXACTLY what i asked for only this 3 or 4 threads ago. So try your .count joke, see how that goes. Or probably this is just a niche goal. Hahaha. Of just go create your custom UDF. Because you offer no collaboration anywhere else on this board.
or try tonys way
AddExtender(`ilcjs44i.dll`,0,`ilcjs64i.dll`) ; Load the JSON extender
json=FileGet(DirScript():"WB64.json")
j = jsParse(json)
kp=jsKeyPaths(j,``)
t=jsValueGet(j,'[WB 64-bit].[Winbatch DLL][0]')
s=jsConMap(t,@jsonvalue)
n=ArrInfo(s,1)
Exit
Ouch. Just trying to keep the conversation lively.
Quote from: bottomleypotts on July 05, 2025, 09:45:10 PMI'm well aware of how json works.
Good to know that you are so "well aware."