Robotframework JSON value iteration - arrays

I'm trying to extract the following data:
["Gunpla","Wood Craft"]
from this JSON
{
"hobby": {
"hobbyList": [
{
"hobbyType": "Art",
"hobbyTypeList": [
{
"hobbyText": "Gunpla",
"hobbyIndex": "1",
"hobbyOrigin": "JPN"
}
]
},
{
"hobbyType": "Art",
"hobbyTypeList": [
{
"hobbyText": "Wood Craft" ,
"hobbyIndex": "2",
"hobbyOrigin": "USA"
}
]
}
]
}
}
Using this simple query. I'm having difficulty extracting "HobbyText" from HobbyTypeListArray.
FOR ${ob_list} IN #{json['hobby']['hobbyList']}
log ${ob_list["hobbyTypeList"][]}
END
Tried to query it explicitly using this JSONPath
$.hobby.hobbyList[.hobbyTypeList[.hobbyText
and expected output should be the same as above mentioned. However, after running it on RBF it returns a parse error
Parse error at 1:33 near token . (.)

Declare index and call selected obj.
FOR ${ob_list} IN #{json['hobby']['hobbyList']}
log ${ob_list["hobbyTypeList"][${index}]['hobbyText]'}
END

Related

In mongoDb, how can I rename a field nested like object-> object -> array -> object -> field?

Sounds messy, I know.
The document I'm modifying is structured like this:
{
"_id":12345,
"name":"harold",
"basicData":{
"devices":[
{
"id":7654,
"relatedJson":{
"make":"sony",
"equipmentID":"asdf"
}
},
{
"id":9493
}
],
"car":"toyota"
}
}
I can't quite get the code right. This is what I have:
db.serviceAgreement.updateMany({"basicData.devices.relatedJson.equipmentID": {$exists: true}},
[
{
$set: {
"basicData.devices": {
$map: {
input: "$basicData.devices", in: {
$mergeObjects: ["$$this.relatedJson",
{equipmentId: "$$this.relatedJson.equipmentID",}]
}
}
}
}
},
{
$unset: "basicData.devices.relatedJson.equipmentID"
}
])
So my understanding of this script is that I'm calling $set to set the field basicData.devices, then I'm setting it to that same list, but before I do that I'm merging the documents relatedJson and a new document {equipmentId : "$$this.relatedJson.equipmentID",} which has the value equipmentId set to the same value as the equipmentID in the relatedJson object.
Then, I'm replacing the relatedJson document with the newly created equipmentId (not my intention).
And finally, deleting the original equipmentID - which doesn't actually exist any more because I've replaced the whole relatedJson object.
How can I insert the new equipmentId into the relatedJson object, instead of replacing it entirely.
I have tried variations of the above script that do all sorts of things, inserting a copy of relatedJson into itself, inserting a copy of devices into relatedJson, deleting everything inside devices, but I can't get it to do what I want.
I feel I'm close to a solution, and maybe I need to modify the $input: but I can't figure out how, or maybe my approach is totally wrong.
Any help would be greatly appreciated.
The end result should be the same document, but relatedJson.equipmentID should be renamed relatedJson.equipmentId (with a lower-case 'd' at the end);
You're close, you just had some syntax issues.
The update should look like this:
db.collection.updateMany({"basicData.devices.relatedJson.equipmentID": {$exists: true}},
[
{
$set: {
"basicData.devices": {
$map: {
input: "$basicData.devices",
in: {
$mergeObjects: [
"$$this",
{
$cond: [
{
$ne: [
"$$this.relatedJson",
undefined
]
},
{
relatedJson: {
$mergeObjects: [
"$$this.relatedJson",
{
equipmentId: "$$this.relatedJson.equipmentID"
}
]
}
},
{}
]
}
]
}
}
}
}
},
{
$unset: "basicData.devices.relatedJson.equipmentID"
}
])
Mongo Playground

Iterate through the array and generate a new variable for each element

I have a JSON array stored in a variable which looks like below
{
"Opportunity": {
"QuoteLineItems": {
"QuoteLineItem": {
"ServiceTypeCode": "CC",
"PhaseLevel": "1",
"Quantity": "1",
"UnitPrice": "2,854.50",
"InvoicedSinceLast": "0.00",
"LevelItems": {
"LevelItem": {
"PhaseLevelItemNumber": "R072",
"DocumentNotes": {
"Note": null
}
}
},
"Colonies": {
"ColonyStage": {
"QuoteColonyLineNumber": "1",
"StageItems": {
"StageItem": {
"StageLineProperty": "CHARGE",
"StageQuoteItemNumber": "ICM_033",
"DocumentNotes": {
"Note": null
}
}
}
}
}
}
},
"QuoteLineItem": {
I need to iterate through each of the QuoteLineItem and generate a new json variable for each Item so I am using the For each element like below
Inside the For each I am having a transform Messgae to generate a new json like below
%dw 2.0
output application/json
---
{
"productCode" : //Not sure how to access the ServiceTypeCode on the QuoteLineItem
"axSequenceNumber" : vars.counter,
}
How do I get the ServiceTypeCode for each QuoteLineItem in the transform message inside the for each loop. I a new to Mulesoft and any help is greatly appreciated
QuoteLineItem is an object, not an array, so you can't use it to iterate. Instead you can use the multi-value selector to retrieve all matching keys as an array and use that to iterate:
<foreach doc:name="For Each" collection="#[payload.Opportunity.QuoteLineItems.*QuoteLineItem]">
Inside the foreach you receive each element of the input array as the payload:
%dw 2.0
output application/json
---
{
"productCode" : payload.ServiceTypeCode
"axSequenceNumber" : vars.counter
}
I'm not sure what you are trying to achieve exactly by storing that into a variable. You should consider if a single transform may not achieve the same results.

Unable to Parse JSON object with double quotes

I am unable to parse nested JSON with in double quotes here is sample object. Flatten do not getting "RawRequest" key due it quoted in double quotes although its valid json:
"Business ID":"Sajidbutta",
"Acout":"Saji_12"
"Report": {
"ReportPDF": {
"RawRequest": "{ \"subcode\" : \"35656\", \"Hoppoes\" :\"Hello\" ,\"Hoppoes\":[{\"tsn\" : \"44544545\", \"title\" : \"Owner\"}] }"
}
}
}
You have two issues.
First, you're missing a comma between "Saji_12" and "Report":
"Acout":"Saji_12" "Report":
The second one is that you're missing the escaping \ in front of the " in the JSON string. Consider the following
{
"Business ID": "Sajidbutta",
"Acout": "Saji_12",
"Report": {
"ReportPDF": {
"RawRequest": "{ \"subcode\" : \"35656\", \"Hoppoes\" :\"Hello\" ,\"Hoppoes\":[{\"tsn\" : \"44544545\", \"title\" : \"Owner\"}] }"
}
}
}
If the "RawRequest" is meant to actually be a json, then the following is appropriate (note the lack of quotation marks after the RawRequest key:
{
"Business ID": "Sajidbutta",
"Acout": "Saji_12",
"Report": {
"ReportPDF": {
"RawRequest": {
"subcode": "35656",
"Hoppoes": "Hello",
"Hoppoes": [
{
"tsn": "44544545",
"title": "Owner"
}
]
}
}
}
}
Note also the duplicate key "Hoppoes" :)

ROKU: Associative Array with multiple values

I have a 2 part question that I am hoping someone can help me with.
I am trying to figure out how to pass an array of years from my server to my ROKU code. It is going to be a variable number of years, meaning there won't always be the same number of elements in the array.
What I need to figure out is how to set up the array, and then how to parse it in BrightScript.
Here is an example of what I have so far. I have the count, but still need to add all the years.
The list of years is 1998,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014
{
"Items" : [
{
"name": "count",
"value": "13"
}
]}
Once it's received in my ROKU code, I will need to loop over the years, and display them, one per line. (I already have the display part done. I just need help knowing how to get at the array elements.)
Since there is so little useful documentation out there for BrightScript arrays, I'm hoping someone with more experience will be able to answer this, and that it will help someone else in the future.
You don't need to do any of that. Just send the JSON array and Roku will parse it:
BrightScript Debugger> myJSON = "[1998,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014]"
BrightScript Debugger> ? type(myJSON)
String
BrightScript Debugger> arr = parseJSON(myJSON)
BrightScript Debugger> ? type(arr)
roArray
It's perfectly valid to have array as top-level element of the json text ("A JSON text is a serialized object or array." per RFC 4627). You can also do it with a dummy object (but why?):
arr = parseJSON(" {"years": [1998, 2003]} ").years
Here is how I solved it:
Array:
{
"Items" : [
{ "value": "2014" } ,
{ "value": "2013" } ,
{ "value": "2012" } ,
{ "value": "2011" } ,
{ "value": "2010" } ,
{ "value": "2009" } ,
{ "value": "2008" } ,
{ "value": "2007" } ,
{ "value": "2006" } ,
{ "value": "2005" } ,
{ "value": "2004" } ,
{ "value": "2003" } ,
{ "value": "1998" }
]
}
BrightScript code to parse it:
arr = CreateObject("roArray",json.Items.count(),false)
for each item in json.Items
thisItem = {
value: item.value
}
arr.push(thisItem)
end for
return arr
I hope this helps someone else in the future.

mongodb - adding the value in a field to the value in an embedded array

I have a document in MongoDB as below.
{
"CorePrice" : 1,
"_id" : 166,
"partno" : 76,
"parttype" : "qpnm",
"shipping" :
[
{
"shippingMethod1" : "ground",
"cost1" : "10"
},
{
"shippingMethod2" : "air",
"cost2" : "11"
},
{
"shippingMethod3" : "USPS",
"cost3" : "3"
},
{
"shippingMethod4" : "USPS",
"cost4" : 45
}
]
}
My goal is to add CorePrice (1) to cost4 (45) and retrieve the computed value as a new column "dpv". I tried using the below query. However I receive an error exception: $add only supports numeric or date types, not Array. I'm not sure why. Any kind of help will be greatly appreciated.
db.Parts.aggregate([
{
$project: {
partno: 1,
parttype: 1,
dpv: {$add: ["$CorePrice","$shipping.cost1"]}
}
},
{
$match: {"_id":{$lt:5}}
}
]);
When you refer to the field shipping.cost1 and shipping is an array, MongoDB does not know which entry of the shipping-array you are referring to. In your case there is only one entry in the array with a field cost1, but this can't be guaranteed. That's why you get an error.
When you are able to change your database schema, I would recommend you to turn shipping into an object with a field for each shipping-type. This would allow you to address these better. When this is impossible or would break some other use-case, you could try to access the array entry by numeric index (shipping.0.cost1).
Another thing you could try is to use the $sum-operator to create the sum of all shipping.cost1 fields. When there is only one element in the array with a field cost1, the result will be its value.
I am able to achieve this by divorcing the query into two as below.
var pipeline1 = [
{
"$unwind": "$shipping"
},
{
$project:{
partno:1,
parttype:1,
dpv:{
$add:["$CorePrice","$shipping.cost4"]
}
}
},
{
$match:{"_id":5}
}
];
R = db.tb.aggregate( pipeline );

Resources