Question about combine/merge json files
Hi All,
I would like to merge json files. From a BPL we're running an operation to get data from a REST service cursors. We would like to run the REST calls until no cursor is present in the response of the rest call.
This works fine, but I would like to combine/merge the json outcome and write it to the disk.
See my attempt below for merging 2 json files.
Class Test.TestClass
{
ClassMethod xxx() As %Status
{
Set tSc = $$$OK
set jsonObj1 = {}.%FromJSON("C:\temp\1.json")
set jsonObj2 = {}.%FromJSON("C:\temp\2.json")
Do jsonObj1.%Remove("NextCursor")
Do jsonObj2.%Remove("NextCursor")
set obj2 = jsonObj2.%Get("OptOuts")
Do jsonObj1.%Set("", obj2)
Set objString = jsonObj1.%ToJSON()
set formatter = ##class(%JSON.Formatter).%New()
Do formatter.FormatToStream(jsonObj1, .Streamobj)
Set ResponseStream = ##class(%Stream.FileBinary).%New()
Set ResponseStream.Filename = "C:\temp\3.json"
Do ResponseStream.CopyFrom(.Streamobj)
Set tSC = ResponseStream.%Save()
Do ResponseStream.%Close()
return tSc
}
}
This gives an outcome but there's an extra node created, see 3.json. I think this make sense if i check rule with " Do jsonObj1.%Set("", obj2)".
.png)
Any advise is welcome how to solve this.
See atttached, 1.json, 2.json
3.json = current result
4.json = wanted result
Comments
Hi Menno,
Currently your solution creates an "extra" node because of the code Do jsonObj1.%Set("", obj2). %Set will always create a new node with parameter 1 as the key and parameter 2 as the value.
It seems like what you really want to do is append all of the objects in obj2.OptOuts with obj1.OptOuts. You can do this by iterating through Obj2.OptOuts and using %Push to append each to Obj1.OptOuts. I've modified the code you provided to accomplish this:
Class Test.TestClass
{
ClassMethod xxx() As %Status
{
Set tSc = $$$OK
Set jsonObj1 = {}.%FromJSON("C:\temp\1.json")
Set jsonObj2 = {}.%FromJSON("C:\temp\2.json")
Do jsonObj1.%Remove("NextCursor")
Do jsonObj2.%Remove("NextCursor")
Set obj1 = jsonObj1.%Get("OptOuts")
Set obj2 = jsonObj2.%Get("OptOuts")
Set OptOuts2Iter = obj2.%GetIterator()
While OptOuts2Iter.%GetNext(.key , .value ) {
Do obj1.%Push(value)
}
Set objString = jsonObj1.%ToJSON()
Set formatter = ##class(%JSON.Formatter).%New()
Do formatter.FormatToStream(jsonObj1, .Streamobj)
Set ResponseStream = ##class(%Stream.FileBinary).%New()
Set ResponseStream.Filename = "C:\temp\3.json"
Do ResponseStream.CopyFrom(.Streamobj)
Set tSc = ResponseStream.%Save()
Do ResponseStream.%Close()
Return tSc
}
}If I understand you correctly, all you have to do is a short loop:
ClassMethod Merge(obj...)
{
set res=obj(1)
do res.%Remove("NextCursor")
for i=2:1:obj do res.OptOuts.%Push(obj(i).OptOuts)
quit res
}do Merge(json1, json2, json3, ...)Of course, my loop is a little bit too short ;-( the correct one is
ClassMethod Merge(obj...) {
set res=obj(1)
do res.%Remove("NextCursor")
for i=2:1:obj {
for j=0:1:obj(i).OptOuts.%Size()-1 do res.OptOuts.%Push(obj(i).OptOuts.%Get(j))
}
quit res
}Sorry, it seems, a telephone call and writing does not go together.
Thank you @Alister Pino and @Julius Kavay for your help.
In this scenario see the final solution below:
ClassMethod MergeDynamicObjects(ObjComplete As %Library.DynamicObject, ObjAddendum As %Library.DynamicObject) [ Final ]{ Set obj1 = ObjComplete.%Get("OptOuts") Set obj2 = ObjAddendum.%Get("OptOuts")
Set OptOuts2Iter = obj2.%GetIterator()
While OptOuts2Iter.%GetNext(.key , .value ) {
Do obj1.%Push(value)
} return ObjComplete}