VBScript Object Compose - json

So i'm using a vbscript code through my Com Objects in order to decode a json file
at first my VBs code was:
Function filejson(json)
On Error Resume Next
Dim objStream, strData
Set objStream = CreateObject("ADODB.Stream")
objStream.CharSet = "utf-8"
objStream.Open
objStream.LoadFromFile(json)
strData = objStream.ReadText()
filejson=strData
End Function
Function str2json(json,value)
On Error Resume Next
Set scriptControl = CreateObject("MSScriptControl.ScriptControl")
scriptControl.Language = "JScript"
Set searchResultObject = scriptControl.Eval("(" + json + ")")
str2json=Eval("searchResultObject" & value )
End Function
Function result(json,value)
On Error Resume Next
result=str2json(filejson(json),value)
End Function
So i was just taking every value i wanted just with
result("movie.json",".adult") for example:
With Json:
{"adult":false,"backdrop_path":"/hbn46fQaRmlpBuUrEiFqv0GDL6Y.jpg"}
And i was taking just fine the "false"
But then , my jsons got more tricky...
{"adult":false,"backdrop_path":"/hbn46fQaRmlpBuUrEiFqv0GDL6Y.jpg","belongs_to_collection":{"id":86311,"name":"The Avengers Collection","poster_path":"/qJawKUQcIBha507UahUlX0keOT7.jpg","backdrop_path":"/zuW6fOiusv4X9nnW3paHGfXcSll.jpg"}}
But still i was able to get data from there with my second argument: ".belongs_to_collection.id" Until THIS:
{
"adult": false,
"backdrop_path": "/hbn46fQaRmlpBuUrEiFqv0GDL6Y.jpg",
"belongs_to_collection": {
"id": 86311,
"name": "The Avengers Collection",
"poster_path": "/qJawKUQcIBha507UahUlX0keOT7.jpg",
"backdrop_path": "/zuW6fOiusv4X9nnW3paHGfXcSll.jpg"
},
"alternative_titles": {
"titles": [
{
"iso_3166_1": "IT",
"title": "I vendicatori"
},
{
"iso_3166_1": "BR",
"title": "Os Vingadores"
},
{
"iso_3166_1": "GB",
"title": "Avengers Assemble"
},
{
"iso_3166_1": "US",
"title": "Marvel's The Avengers"
},
{
"iso_3166_1": "SE",
"title": "Avengers 3D"
},
{
"iso_3166_1": "ES",
"title": "Marvel Los Vengadores"
},
{
"iso_3166_1": "PL",
"title": "Avengers 3D"
},
{
"iso_3166_1": "IL",
"title": "הנוקמים"
},
{
"iso_3166_1": "US",
"title": "The Avengers 3D"
},
{
"iso_3166_1": "CZ",
"title": "Avengers"
},
{
"iso_3166_1": "TW",
"title": "復仇者聯盟"
},
{
"iso_3166_1": "DE",
"title": "Marvel's The Avengers - Die Rächer"
},
{
"iso_3166_1": "DE",
"title": "The Avengers - Die Rächer"
},
{
"iso_3166_1": "VE",
"title": "Los Vengadores"
}
]
}
}
And i tried to get one of the alternative titles, i tried with my default method...
result("movie.json",".alternative_titles.titles.0.title") but null was what i got...
So i used it for
result("movie.json",".alternative_titles.titles") to check the result
and the result was:
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
After some time trying to figure out what to do since i couldn't access the sub object with a simple number (.1 , .0 ...) i tried to create a function to do things a bit more easier, though failed:
Function filejson(json)
On Error Resume Next
Dim objStream, strData
Set objStream = CreateObject("ADODB.Stream")
objStream.CharSet = "utf-8"
objStream.Open
objStream.LoadFromFile(json)
strData = objStream.ReadText()
filejson=strData
End Function
Function str2json(json,value)
On Error Resume Next
Set scriptControl = CreateObject("MSScriptControl.ScriptControl")
scriptControl.Language = "JScript"
Set searchResultObject = scriptControl.Eval("(" + json + ")")
parameters=Split(value,".")
fullparm="obj"
obj=Eval("searchResultObject" & fullparm )
For Each parm in parameters
MsgBox("Parameter: "&parm&" | Old Object: "& obj)
If Eval("obj."&parm) = "[object Object]" Then
If IsNumeric(parm) Then
i=0
For Each new_obj in obj
If Trim(i) = Trim(parm) then
MsgBox("New Object: " & "obj | Value: " & new_obj)
obj=new_obj
fullparm="obj."
End If
i=i+1
Next
Else
obj=Eval("obj." & parm)
fullparm=fullparm&"."&parm
MsgBox("New Object: " & "obj." & parm & " | Value: " & obj)
End If
Else
str2json=obj
Exit Function
End If
Next
MsgBox(fullparm)
str2json="false"
End Function
Function result(json,value)
On Error Resume Next
result=str2json(filejson(json),value)
End Function
Any ideas how to manage to Get the value i want by just having the same input?
"alternative_titles.titles.0.title" (get 1 sub object.title).
Also it could have more than one sub dimension...jsons....
And i HAVE to use VBScript and NOT JScript. It used within combojects.
with JScript its not able to open a file with UTF8. IN VBScript it is with ADODB.Stream

sometime ago, I wrote a JSON to XMLDOM converter (see Decode/Encode JSON with VBScript
). When applied to your JSON, it produces the following XMLDOM:
<OBJECT adult="false" backdrop_path="/hbn46fQaRmlpBuUrEiFqv0GDL6Y.jpg">
<OBJECT id="86311" name="The Avengers Collection" poster_path="/qJawKUQcIBha507UahUlX0keOT7.jpg" backdrop_path="/zuW6fOiusv4X9nnW3paHGfXcSll.jpg"/>
<OBJECT>
<ARRAY>
<OBJECT iso_3166_1="IT" title="I vendicatori"/>
<OBJECT iso_3166_1="BR" title="Os Vingadores"/>
<OBJECT iso_3166_1="GB" title="Avengers Assemble"/>
<OBJECT iso_3166_1="US" title="Marvel's The Avengers"/>
<OBJECT iso_3166_1="SE" title="Avengers 3D"/>
<OBJECT iso_3166_1="ES" title="Marvel Los Vengadores"/>
<OBJECT iso_3166_1="PL" title="Avengers 3D"/>
<OBJECT iso_3166_1="IL" title="הנוקמים"/>
<OBJECT iso_3166_1="US" title="The Avengers 3D"/>
<OBJECT iso_3166_1="CZ" title="Avengers"/>
<OBJECT iso_3166_1="TW" title="復仇者聯盟"/>
<OBJECT iso_3166_1="DE" title="Marvel's The Avengers - Die Rächer"/>
<OBJECT iso_3166_1="DE" title="The Avengers - Die Rächer"/>
<OBJECT iso_3166_1="VE" title="Los Vengadores"/>
</ARRAY>
</OBJECT>
</OBJECT>
As an XMLDOM it should be a simple matter of using XPath queries and selectSingleNode to get the values you want. For example: Select Single Node with a attribute name in vbscript

I don't know if you still have this issue, but I found the way to access the list array objects using the script control. When addressing the member you can use square brackets around the index number e.g. obj.[index#]. Hope this helps!
Not sure if it's relevant either, but to get a variable index of an object in this case I found I have to use the eval() function. Here's an example of what I'm doing for my JSON array where count is the number of objects in the array:
Do While index < count
types(index) = eval(".Data.Array.[" & cstr(index) &"].Type")
index = index + 1
Loop

Related

"Cannot deserialize the current JSON object" How to fix this error?

I'm not sure how to fix the following error and am looking for some help in this code I found that I have attempted to adapt for use in application embedded VB.Net:
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[System.Object]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'error', line 1, position 9.
Below is the code That is generating this error
Dim OutputText As String
Dim Worksteps = JsonConvert.DeserializeObject(Of List(Of Object))(responseFromServer)
Dim token As JToken
Dim SheetName As String
Dim SheetStatus As String
Dim Completed As Boolean
For Each value As Object In Worksteps
token = JObject.Parse(value.ToString())
SheetName = token.SelectToken("name")
SheetStatus = token.SelectToken("status")
Dim parts() As String = SheetName.Split(" "c)
If parts(0) = "Sheet_1" Then
If SheetStatus = "COMPLETED" Then
Completed = True
Exit For
End If
End If
Next value
Select Case Completed
Case True
OutputText = "Sheet_1 Status is COMPLETED"
Case False
OutputText = "Sheet_1 Status is NOT COMPLETED"
End Select
Here is the JSON I'm attempting to parse. My assumption is that I somehow need to first parse for the Worksteps before trying to make a list of worksteps but I'm not sure how to do that.
{
"error": null,
"worksteps": [
{
"id": "_210504_125916572_029875",
"name": "Sheet_1 4/4",
"job": {
"id": "060671-21",
"name": "2021 Laramie High School"
},
"status": "COMPLETED",
"amountPlanned": 544,
"wastePlanned": 60,
"amountProduced": 169,
"wasteProduced": 69,
"deviceId": "114",
"types": [
"ConventionalPrinting"
],
"sequenceType": "SheetfedPrinting",
"start": "2021-05-05T09:46:06-05:00",
"end": "2021-05-05T09:48:38-05:00",
"startPlanned": "2021-05-05T07:52:22-05:00",
"endPlanned": null,
"setuptimePlanned": 0,
"prodtimePlanned": 0,
"actualTimes": [
{
"timeTypeGroupName": "Production time",
"timeTypeName": "Execution time",
"duration": 33
},
{
"timeTypeGroupName": "Production time",
"timeTypeName": "Setup time",
"duration": 79
},
{
"timeTypeGroupName": "Auxiliary time",
"timeTypeName": "Auxiliary time",
"duration": 40
},
{
"timeTypeGroupName": "",
"timeTypeName": "",
"duration": 0
}
]
},
{
"id": "_210506_072306983_020035",
"name": "Sheet_2 4/4",
"job": {
"id": "060671-21",
"name": "2021 Laramie High School"
},
"status": "WAITING",
"amountPlanned": 0,
"wastePlanned": 0,
"amountProduced": 0,
"wasteProduced": 0,
"deviceId": "XL106_Pool",
"types": [
"ConventionalPrinting"
],
"sequenceType": "SheetfedPrinting",
"start": null,
"end": null,
"startPlanned": null,
"endPlanned": null,
"setuptimePlanned": 0,
"prodtimePlanned": 0,
"actualTimes": null
}
]
}
Here is the solution I came up with to convert JSON sample above to XML and then extract the values for the sheet and status:
'Parse the JSON responseFromServer into an XMLDocument
Dim xdoc As New XmlDocument
' "job_worksteps" is the name being provided
xdoc = JsonConvert.DeserializeXmlNode(responseFromServer,"job_worksteps")
' Look in the XML to determine the if a specified sheet has been completed
Dim nodes As XmlNodeList = xdoc.DocumentElement.SelectNodes("/job_worksteps/worksteps")
Dim Completed As Boolean
Dim SheetName, SheetStatus, OutputText As String
Dim TargetSheet As String = "Sheet_" + triggerEvent.String2 ' Integer as string included in the Prinergy RBA Trigger HTTP Post
' Loop through the XML nodes to find the SheetName node "name" and SheetStatus node "status"
For Each node As XmlNode In nodes
SheetName = node.SelectSingleNode("name").InnerText
SheetStatus = node.SelectSingleNode("status").InnerText
Dim parts() As String = SheetName.Split(" ")
' Validate the TargetSheet name has a Status of "COMPLETED"
If parts(0) = TargetSheet Then
If SheetStatus = "COMPLETED" Then
Completed = True
Exit For
End If
End If
Next
' Format the output we want for this test
' (The final Boolean value will actually be used to trigger another function if it is True)
Select Case Completed
Case True
OutputText = "Sheet_1 Status is COMPLETED"
Case False
OutputText = "Sheet_1 Status is NOT COMPLETED"
End Select
Here is the resulting XML from some additional code to append it to the OutputText variable:
Sheet_1 Status is COMPLETED
<job_worksteps>
<error />
<worksteps>
<id>_210505_073301677_027121</id>
<name>Sheet_1 4/4</name>
<job>
<id>060671-21</id>
<name>2021 Laramie High School</name>
</job>
<status>COMPLETED</status>
<amountPlanned>544</amountPlanned>
<wastePlanned>60</wastePlanned>
<amountProduced>169</amountProduced>
<wasteProduced>69</wasteProduced>
<deviceId>114</deviceId>
<types>ConventionalPrinting</types>
<sequenceType>SheetfedPrinting</sequenceType>
<start>2021-05-05T09:46:06-05:00</start>
<end>2021-05-05T09:48:38-05:00</end>
<startPlanned>2021-05-05T07:52:22-05:00</startPlanned>
<endPlanned />
<setuptimePlanned>0</setuptimePlanned>
<prodtimePlanned>0</prodtimePlanned>
<actualTimes />
</worksteps>
<worksteps>
<id>_210505_073301714_027146</id>
<name>Sheet_2 4/4</name>
<job>
<id>060671-21</id>
<name>2021 Laramie High School</name>
</job>
<status>WAITING</status>
<amountPlanned>0</amountPlanned>
<wastePlanned>0</wastePlanned>
<amountProduced>0</amountProduced>
<wasteProduced>0</wasteProduced>
<deviceId>XL106_Pool</deviceId>
<types>ConventionalPrinting</types>
<sequenceType>SheetfedPrinting</sequenceType>
<start />
<end />
<startPlanned />
<endPlanned />
<setuptimePlanned>0</setuptimePlanned>
<prodtimePlanned>0</prodtimePlanned>
<actualTimes />
</worksteps>
</job_worksteps>
--

How to parse json string in vb6

I'm calling a web service in VB6 which returns a json string as response. I'm able to hold the response in a string. now I want to show the each parameter separately how can I extract the values from the string ?. a sample string is here :
{
"id": "22144",
"t" : "AAPL",
"e" : "NASDAQ",
"l" : "108.00",
"l_fix" : "108.00",
"l_cur" : "108.00",
"s": "2",
"ltt":"4:00PM EDT",
"lt" : "Aug 10, 4:00PM EDT",
"lt_dts" : "2016-08-10T16:00:01Z",
"c" : "-0.81",
"c_fix" : "-0.81",
"cp" : "-0.74",
"cp_fix" : "-0.74",
"ccol" : "chr",
"pcls_fix" : "108.81",
"el": "107.98",
"el_fix": "107.98",
"el_cur": "107.98",
"elt" : "Aug 10, 5:16PM EDT",
"ec" : "-0.02",
"ec_fix" : "-0.02",
"ecp" : "-0.02",
"ecp_fix" : "-0.02",
"eccol" : "chr",
"div" : "0.57",
"yld" : "2.11"
}
I've found VB-JSON works really well for parsing json in VB6.
You can download it from here.
VB-JSON: A Visual Basic 6 (VB6) JSON Parser Class Library
The .zip file that you download will contain a sample project and the library, which is called JSON.bas.
The main parser function is JSON.parse and you pass it the json string as parameter.
So in your project, you only need to include / add the JSON.bas file.
Sample Usage (from the sample project) :
Private Sub cmdObjToJSON_Click()
Dim p As Object
Dim sInputJson As String
sInputJson = "{ width: '200', frame: false, height: 130, bodyStyle:'background-color: #ffffcc;',buttonAlign:'right', items: [{ xtype: 'form', url: '/content.asp'},{ xtype: 'form2', url: '/content2.asp'}] }"
MsgBox "Input JSON string: " & sInputJson
' sets p
Set p = JSON.parse(sInputJson)
MsgBox "Parsed object output: " & JSON.toString(p)
MsgBox "Get Bodystyle data: " & p.Item("bodyStyle")
MsgBox "Get Form Url data: " & p.Item("items").Item(1).Item("url")
p.Item("items").Item(1).Add "ExtraItem", "Extra Data Value"
MsgBox "Parsed object output with added item: " & JSON.toString(p)
End Sub
As it applies to your case. Something like the following might work (with some tweaks if needed).
Dim parsedJsonObject As Object
Set parsedJsonObject = JSON.parse(yourJsonStringVariable)
'Print the ticker ( t in your json )
Debug.Print parsedJsonObject.Item("t")
There is a JSON parser library for Visual Basic that you can find in http://json.org/.
You can either use VB-JSON or PW.JSON.

How to format json in a file using Groovy

I have a question in regards to formatting a file so that it displays a Json output to the correct format.
At the moment the code I have below imports a json into a file but when I open the file, it displays the json in a single line (word wrap unticked) like so:
{"products":[{"type":null,"information":{"description":"Hotel Parque La Paz (One Bedroom apartment) (Half Board) [23/05/2017 00:00:00] 7 nights","items":{"provider Company":"Juniper","provider Hotel ID":"245","provider Hotel Room ID":"200"}},"costGroups":[{"name":null,"costLines":[{"name":"Hotel Cost","search":null,"quote":234.43,"quotePerAdult":null,"quotePerChild":null}
I want to format the json in the file so that it looks like actual json formatting like so:
{
"products": [
{
"type": null,
"information": {
"description": "Hotel Parque La Paz (One Bedroom apartment) (Half Board) [23/05/2017 00:00:00] 7 nights",
"items": {
"provider Company": "Juniper",
"provider Hotel ID": "245",
"provider Hotel Room ID": "200"
}
},
"costGroups": [
{
"name": null,
"costLines": [
{
"name": "Hotel Cost",
"search": null,
"quote": 234.43,
"quotePerAdult": null,
"quotePerChild": null
}
Virtually each header has its own line to contain its values.
What is the best way to implement this to get the correct json formatting within the file?
Below is the code:
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)
def dataFolder = groovyUtils.projectPath +"//Log Data//"
def response = testRunner.testCase.getTestStepByName("GET_Pricing{id}").getProperty("Response").getValue();
def jsonFormat = (response).toString()
def fileName = "Logged At - D" +date+ " T" +time+ ".txt"
def logFile = new File(dataFolder + fileName)
// checks if a current log file exists if not then prints to logfile
if(logFile.exists())
{
log.info("Error a file named " + fileName + "already exisits")
}
else
{
logFile.write "Date Stamp: " +date+ " " + time + "\n" + jsonFormat //response
If you have a modern version of groovy, you can do:
JsonOutput.prettyPrint(jsonFormat)

i got empty value when print json key in lua code

this is the json response plus "\x00" in the end from server :
{
"STATUS": [{
"STATUS":"S",
"When":1470180059,
"Code":11,
"Msg":"Summary",
"Description":"nsgminer 0.9.2"
}],"SUMMARY": [{
"Elapsed":2061,
"MHS av":0.00,
"Found Blocks":0,
"Getworks":76,
"Accepted":0,
"Rejected":0,
"Hardware Errors":0,
"Utility":0.00,
"Discarded":209,
"Stale":0,
"Get Failures":3,
"Local Work":293,
"Remote Failures":0,
"Network Blocks":14,
"Total MH":0.0000,
"Work Utility":0.00,
"Difficulty Accepted":0.00000000,
"Difficulty Rejected":0.00000000,
"Difficulty Stale":0.00000000,
"Best Share":0
}],
"id":1
}\x00
i want to use the json in lua code :
local output = stdnse.output_table()
local json_string = tostring(result:sub(1, -2))
local pos, value = json.parse(json_string)
output["Description"] = value["STATUS"][0]["Description"]
return output
when i print it out, i got null value
i solve that with covert json to string and convert string into json table
local pos, value = json.parse(tostring(json_string))
output["Description"] = value["STATUS"][1]["Description"]

json.net check if children exists

I have some json and parse the content using json.net. Firstly I use the JToken and split the fields from a post into a list of objects and then read the values from each. The problem is that some of these objects sometimes have the fields and sometimes dont and not sure how to prevent a nullexception error from being called. Here is the json sample:
{"id": "dfdksfjaisdfdsjfksdjdfsdafernd"}
{"body": "test data for parsing"}
{"object": { "summary":"hello test data you trouble maker", "id" :"problem stuff",
"link": "http://testdata.com",
"objecttype": "link"
}}
{"user": { "name": "Joe Somebody", "age":"43", "location": { "name": "outer space"},
}
}
Now in some posts the location field is not present in user object which results in a null error in my code as shown below and also sometime the object object is in a different format as follows:
{"id": "dfdksfjaisdfdsjfksdjdfsdafernd"}
{"body": "test data for parsing"}
{"object": { "object":
{"summary":"hello test data you trouble maker", "id" :"problem stuff",
"link": "http://testdata.com",
"objecttype": "link"
}
}}
{"user": { "name": "Joe Somebody", "age":"43",
}
}
now if my code is as follows:
Dim results As List(Of JToken) = jobj.Children().ToList
If results.Count = 0 Then
Exit Sub
End If
For Each item As JProperty In results
item.CreateReader()
If item.Name = "id" Then
id = item.Value
End If
If item.Name = "actor" Then
author = item.Value("name").ToString
location = item.Value("location").Item("name").ToString
age = item.Value("age").ToString
End If
If item.Name = "object" Then
htext = item.Value("summary").ToString
csubject = item.Value("objectType").ToString
End If
Next
Then if location and object are different this code will not work. so how can I check to see if the location field is present and also if the object path is different with another object within it before the summary field.
EDIT:
Ok thought I figured it out with
If Not item.Value("location") Is Nothing Then
bla bla bla
Ok I guess it did work and null exception from illformed json:
If Not item.Value("location") Is Nothing Then
bla bla bla
and the same for the object
If Not item.Value("summary") Is Nothing Then
bla bla bla
else
htext = item.Value("object").Item("summary").tostring