YAJL and nested JSON Arrays

Discussions relating to the ScottKlement.com port of the open source YAJL JSON Reader/Generator. This includes the YAJL tool as well as the YAJLR4, YAJLGEN, YAJLINTO and YAJLDTAGEN add-ons from ScottKlement.com. http://www.scottklement.com/yajl/
Post Reply
mobergmann@gmail.com
Posts: 3
Joined: Mon Jan 23, 2023 10:45 pm

YAJL and nested JSON Arrays

Post by mobergmann@gmail.com »

Hi Scott,

I'm new to using YAJL so could use some guidance on handling nested objects/arrays.

I've attached my JSON response which I am loading from a *STMF.
I'm able to locate the node for the tracking object and shipment array.
I was hoping to get the node for the "package" array using the shipment node (shpNode) but that is returning nulls.

So, I'm using the node for the shipment array (shpNode) to try and drill down to ultimately get to the package array and then the delivery date array.
This is where I'm getting a little lost.

When looping through the shipment array looking for my ojbects, I can ultimately get "key" to resolve to a value of "package".
I tried to use yajl_find_object to get to the deliveryDate array but I know that is wrong and I'm pretty turned around at this point.


If you can provide some guidance on what my next step in the code should be I'd appreciate it.

Code: Select all

dcl-s trkNode  like(docNode);   
dcl-s shpNode  like(docNode);  
dcl-s delNode  like(docNode); 
dcl-s node     like(yajl_val);  
dcl-s list     like(yajl_val);  
dcl-s val      like(yajl_val);  
dcl-s valnum   zoned(5:0) Inz;  
dcl-s valStr   like(resultStr); 
dcl-s errMsg   varchar(500);    
dcl-s i        int(10) inz;     
dcl-s j        int(10) inz;  

D resultStmf      s           5000a   varying    
                                

// parse JSON                                                    
   docNode = yajl_stmf_load_tree(resultStmf               
                                :Errmsg);                        
                                                                 
   If errMsg = ' ';                                              
                                                                 
     trkNode = yajl_object_find (docNode : 'trackResponse');       
     shpNode = yajl_object_find (trkNode : 'shipment');
     //pkgNode = yajl_object_find (shpNode : 'package);              //returns nulls            
                                                                 
     i = 0;                                                      
     Dow yajl_array_loop(shpNode : i : node);                        
                                                                 
       j = 0;                                                    
       Dow yajl_object_loop(node : j : key : val);                     
                                                                 
         If key = 'package';                                       
           delNode = yajl_Object_find (node : 'deliveryDate');                            
         Endif;                                   
                                                      
       Enddo;                                     
     Enddo;                                       
   Endif;
Here is the JSON response I'm working with...

Code: Select all

{
	"trackResponse": {
		"shipment": [
			{
				"inquiryNumber": "1Z3794540215045372",
				"package": [
					{
						"trackingNumber": "1Z3794540215045372",
						"deliveryDate": [
							{
								"type": "DEL",
								"date": "20221010"
							}
						],
						"deliveryTime": {
							"type": "DEL",
							"endTime": "150653"
						},
						"activity": [
							{
								"location": {
									"address": {
										"city": "TRENTON",
										"stateProvince": "NJ",
										"countryCode": "US",
										"country": "US"
									},
									"slic": "0863"
								},
								"status": {
									"type": "D",
									"description": "DELIVERED ",
									"code": "FS",
									"statusCode": "011"
								},
								"date": "20221010",
								"time": "150653"
							},
							{
								"location": {
									"address": {
										"city": "Hamilton",
										"stateProvince": "NJ",
										"countryCode": "US",
										"country": "US"
									},
									"slic": "0863"
								},
								"status": {
									"type": "I",
									"description": "Out For Delivery Today",
									"code": "OT",
									"statusCode": "021"
								},
								"date": "20221010",
								"time": "085730"
							},
							{
								"location": {
									"address": {
										"city": "Hamilton",
										"stateProvince": "NJ",
										"countryCode": "US",
										"country": "US"
									},
									"slic": "0860"
								},
								"status": {
									"type": "I",
									"description": "Processing at UPS Facility",
									"code": "DS",
									"statusCode": "087"
								},
								"date": "20221010",
								"time": "060250"
							},
							{
								"location": {
									"address": {
										"city": "Hamilton",
										"stateProvince": "NJ",
										"countryCode": "US",
										"country": "US"
									},
									"slic": "0799"
								},
								"status": {
									"type": "I",
									"description": "Arrived at Facility",
									"code": "AR",
									"statusCode": "005"
								},
								"date": "20221009",
								"time": "162200"
							},
							{
								"location": {
									"address": {
										"city": "Parsippany",
										"stateProvince": "NJ",
										"countryCode": "US",
										"country": "US"
									},
									"slic": "0799"
								},
								"status": {
									"type": "I",
									"description": "Departed from Facility",
									"code": "DP",
									"statusCode": "005"
								},
								"date": "20221009",
								"time": "145200"
							},
							{
								"location": {
									"address": {
										"city": "Parsippany",
										"stateProvince": "NJ",
										"countryCode": "US",
										"country": "US"
									},
									"slic": "1949"
								},
								"status": {
									"type": "I",
									"description": "Arrived at Facility",
									"code": "AR",
									"statusCode": "005"
								},
								"date": "20221008",
								"time": "131300"
							},
							{
								"location": {
									"address": {
										"city": "Philadelphia",
										"stateProvince": "PA",
										"countryCode": "US",
										"country": "US"
									},
									"slic": "1949"
								},
								"status": {
									"type": "I",
									"description": "Departed from Facility",
									"code": "DP",
									"statusCode": "005"
								},
								"date": "20221008",
								"time": "094800"
							},
							{
								"location": {
									"address": {
										"city": "Philadelphia",
										"stateProvince": "PA",
										"countryCode": "US",
										"country": "US"
									},
									"slic": "3269"
								},
								"status": {
									"type": "I",
									"description": "Arrived at Facility",
									"code": "AR",
									"statusCode": "005"
								},
								"date": "20221007",
								"time": "211700"
							},
							{
								"location": {
									"address": {
										"city": "Orlando",
										"stateProvince": "FL",
										"countryCode": "US",
										"country": "US"
									},
									"slic": "3269"
								},
								"status": {
									"type": "I",
									"description": "Departed from Facility",
									"code": "DP",
									"statusCode": "005"
								},
								"date": "20221007",
								"time": "035100"
							},
							{
								"location": {
									"address": {
										"city": "Orlando",
										"stateProvince": "FL",
										"countryCode": "US",
										"country": "US"
									},
									"slic": "3269"
								},
								"status": {
									"type": "I",
									"description": "Arrived at Facility",
									"code": "AR",
									"statusCode": "005"
								},
								"date": "20221007",
								"time": "030500"
							},
							{
								"location": {
									"address": {
										"city": "Orlando",
										"stateProvince": "FL",
										"countryCode": "US",
										"country": "US"
									},
									"slic": "3269"
								},
								"status": {
									"type": "I",
									"description": "Departed from Facility",
									"code": "DP",
									"statusCode": "005"
								},
								"date": "20221007",
								"time": "030300"
							},
							{
								"location": {
									"address": {
										"city": "Orlando",
										"stateProvince": "FL",
										"countryCode": "US",
										"country": "US"
									},
									"slic": "3289"
								},
								"status": {
									"type": "I",
									"description": "Arrived at Facility",
									"code": "AR",
									"statusCode": "005"
								},
								"date": "20221006",
								"time": "222000"
							},
							{
								"location": {
									"address": {
										"city": "Orlando",
										"stateProvince": "FL",
										"countryCode": "US",
										"country": "US"
									},
									"slic": "3289"
								},
								"status": {
									"type": "I",
									"description": "Departed from Facility",
									"code": "DP",
									"statusCode": "005"
								},
								"date": "20221006",
								"time": "221600"
							},
							{
								"location": {
									"address": {
										"city": "Deerfield Beach",
										"stateProvince": "FL",
										"countryCode": "US",
										"country": "US"
									},
									"slic": "3326"
								},
								"status": {
									"type": "I",
									"description": "Origin Scan",
									"code": "OR",
									"statusCode": "005"
								},
								"date": "20221005",
								"time": "202511"
							},
							{
								"location": {
									"address": {
										"countryCode": "US",
										"country": "US"
									}
								},
								"status": {
									"type": "M",
									"description": "Shipper created a label, UPS has not received the package yet. ",
									"code": "MP",
									"statusCode": "003"
								},
								"date": "20221005",
								"time": "141503"
							}
						],
						"packageCount": 1
					}
				],
				"userRelation": [
					"SHIPPER"
				]
			}
		]
	}
}
Scott Klement
Site Admin
Posts: 635
Joined: Sun Jul 04, 2021 5:12 am

Re: YAJL and nested JSON Arrays

Post by Scott Klement »

UPS allows you to track multiple shipments in a given response. So "shipment" is an array -- there's only one in your case, but it's possible for there to be more than one. Likewise, within a given shipment, there can be more than one package. Within a given package, there can (and almost certainly will be) more than one activity.

Does that help?

I'm not exactly sure what you are asking. What do you plan to do with the result?
mobergmann@gmail.com
Posts: 3
Joined: Mon Jan 23, 2023 10:45 pm

Re: YAJL and nested JSON Arrays

Post by mobergmann@gmail.com »

Hi Scott,

Thanks for the speedy reply. Ultimately I'm just trying to parse out the delivery date from the JSON response so it can drive a process to send an automated SMS message to our customers to let them know their package has been delivered.

In my call to the tracking API to UPS I am passing them a specific tracking number, so I am anticipating that I will only see the tracking event history for that tracking number alone. I can get to the "Package" array but I'm a little lost as to what is the best way to go from there to drill down to get to the delivery date array to pick up my value for a "DEL" type.

Hope that is helpful.
M.
Scott Klement
Site Admin
Posts: 635
Joined: Sun Jul 04, 2021 5:12 am

Re: YAJL and nested JSON Arrays

Post by Scott Klement »

The easiest thing would be to use DATA-INTO instead of calling the subprocedures.

But, if you do want to call the subprocedures, package is an array -- so you'd need to tell it which array element you want. (Probably always #1 if you're only expecting one package.) Then within that array element, is an object -- which would contain the "delivery date" array.

So -- off the top of my head without testing...:

Code: Select all

pkgArray = yajl_array_elem(shpNode: 1);
pkgObj = yajl_array_elem(pkgArray: 1);
delArray = yajl_object_find(pkgObj: 'deliveryDate');
delObj = yajl_array_elem(delArray: 1);
delType = yajl_object_find(delObj:'type');
delDate = yajl_object_find(delObj:'date');
mobergmann@gmail.com
Posts: 3
Joined: Mon Jan 23, 2023 10:45 pm

Re: YAJL and nested JSON Arrays

Post by mobergmann@gmail.com »

Thank you Scott. Sorry for the slow reply.
I'll dig into your sample code and exercise it!
M.
Post Reply