Tech Articles


Enhanced JSON handling


Why enhance JSON handling?

Reading and writing JSON in PowerBuilder is simple using PowerBuilder’s RESTClient object; however, the JSON needs to be in a two-dimensional format. But there are times when the JSON you are working with has multiple nested levels, especially if working with data from an external interface not under your control.

The PowerBuilder objects JSONParser and JSONGenerator can be used to parse or generate such JSON with multiple nested levels.  However, a key caveat is that the JSONParser and JSONGenerator require the JSON data to be accessed through “handles”.  For example, the getItemObject() returns a handle rather than the full JSON object.  Compared to an object-based approach, this handle-based approach requires more coding by the developer.

Another thing to keep in mind is that the JSONParser and JSONGenerator cannot directly modify the JSON data.  If you need to do so, you must first parse the JSON file (with the JSONParser), make the desired changes, and regenerate the JSON again (with the JSONGenerator) - or even merge a part of a JSON file into another one. For such requirements, transforming the data from the JSONParser to the JSONGenerator item by item can be tedious.

Fortunately, I have a solution for that. I've created a nonvisual user object called u_json, which can parse, generate and manipulate JSON in an object oriented way.

 

How it works

u_json works with its own JSON structure. When a file is parsed, it will be completely parsed with JSONParser and then would be available in the object oriented way. When a JSON string is generated, a JSONGenerator object will be created from the object structure.

Each array, object or value is considered a node, each node is represented by an u_json object. Array and object nodes contain an array of u_json objects. With this setup, the JSON information can be easily accessed and manipulated using the dot notation (see examples in the GitHub wiki).

 

Get it, it's open source

I've published the project on GitHub as open source under the MIT license.

Open and download on GitHub

By now, the project isn't thoroughly tested, so there might be some bugs left. But it's working in general. If you find an error or have some ideas how to optimize it, you're very welcome to create an issue or pull request on GitHub. More Information as well as a full function reference can also be found on the GitHub Wiki.

 

Comments (5)
Wednesday, Feb 19 2020

This is great!

I haven't used it myself yet, but I'm pretty convinced I will the minute I have to work with JSON.
Thank you for this effort Georg!

0

Thursday, Jun 11 2020

Awesome work Georg!!!

This is exactly what is missing for PowerBuilder and it's JSON support. Practically, is a DOM oriented approach for the JSON structure.
It's really helpful, if you are intent to use PB + JSON, this is a must!!!!

Thank you Georg!!!!

0

Hi Yiannis

Thanks a lot for your feedback, it's a pleasure to hear that!

Currently, I'm using the framework myself, and did some bugfixes recently - make sure you use the latest version from GitHub. I'm also about to do some further optimizations, I'll add that within the next days.

0

Monday, Nov 16 2020

Hi George! Thanks for this code, is very usefull.
Maybe i'm doing something wrong, but i found some bugs I want to share with you.

When i call the funcion of_delete_node('string') it goes into an infinite loop that closes PB ide.

Instead, i did:

ll_delete_line = lu_json_order.of_get_node('items').of_get_index()
lu_json_order.of_delete_node(ll_delete_line)

ll_delete_line= lu_json_order.of_get_node('billing_address').of_get_index()
lu_json_order.of_delete_node(ll_delete_line)

First time, it works well, but on the second time i execute the order, of_get_index() returns 57 instead the 56 that should be the value returned at of_get_index.

I've solved it by adding the line:

iu_nodes[ll_i].il_index = ll_i

at of_get_node before return

Also, maybe a call to of_changed() should be done at of_delete_node().

As i told you, maybe i'm doing something wrong, or working in an unexpected way.

Anyway, this code works nice for me and will use it onwards, will keep reporting errors or ideas if you want.
Thanks!

0
Tuesday, Nov 17 2020

Hi Alvar!

Thanks a lot for sharing this with me!

You're absolutely right about the of_changed() call which is missing, just added that. Also, there was an error about the re-indexing after deleting a node, which I also just fixed. So thanks a lot for reporting.

Your solution for the indexing problem will not reorganize the indexes in all following nodes, so if there are nodes following, you might end up in more problems. But just get the new version from gitHub, that should solve these problems.

I didn't fully understand your problem with the infinite loop, though. I don't really understand why there should be an infinite loop, and I also can't reproduce. So if you could send me your sample JSON with the code that causes this behaviour, I'd be happy to look into it.

And of course, I'd be very happy if you kept reporting errors or ideas.

Best regards, Georg.

0

Find Articles by Tag

PostgreSQL ODBC driver PBNI Android Database Profile Configuration Design Sort Export TortoiseGit REST TFS Messagging IDE Event Menu .NET DataStore WinAPI NativePDF SqlModelMapper WebBrowser Variable Git InfoMaker Excel Web API RESTClient .NET Assembly PBVM Authorization C# Open Source Model External Functions Array SDK PDFlib Database Painter 64-bit PFC Migration Debug Platform UI Themes JSONGenerator Repository Encryption SnapDevelop OrcaScript XML Azure Elevate Conference Database Table Schema DevOps Testing UI Modernization JSONParser Bug Application TLS/SSL SOAP Windows OS RibbonBar 32-bit Stored Procedure Validation Transaction Charts PowerBuilder Compiler PowerBuilder Graph PowerScript (PS) Source Code PowerServer Mobile Interface DataWindow JSON Outlook iOS PowerServer Web Trial Error MessageBox Database Connection CrypterObject Source Control Script CoderObject COM GhostScript OAuth 2.0 Class Jenkins RichTextEdit Control PowerBuilder (Appeon) .NET Std Framework Expression RibbonBar Builder Resize Linux OS ODBC Import JSON DataWindow License SQL Server Performance DragDrop TreeView Database Object API HTTPClient Web Service Proxy Branch & Merge SnapObjects Import Windows 10 Icons PostgreSQL File Window Filter JSON Icon Database Table Data PDF OAuth DataType Export JSON Database Table Data ActiveX OLE Event Handler Debugger Installation Syntax Automated Testing BLOB CI/CD SVN Event Handling SqlExecutor UI DLL Database Authentication SQL Mobile Visual Studio Oracle PBDOM Text Encoding Service Debugging Deployment