Skip to main content

I’m trying to make use of the JSONUpdater transformer since it seems more clear than doing a search & replace. My issue is I just can’t understand the JSONiq enough to know what I need to do to always find the right JSON Path. 

I’m reading in a JSON template and in this template are 3 objects at json[“flowcontents”][“processors”]. The problem is the order can change for the processors. I might want 0, 1, or 2. The key is the object # I want always has “name : Build-Parameters”.

I’m thinking I have two options.

  1. Is there a way with JSONiq to always specify the correct JSON Path in the JSONUpdater, based on the name of each object.
  2. Maybe I sort the processors objects in the JSON prior to the JSONUpdater transformer. Then I always specify the correct one to find path. (Thankfully the order doesn’t matter when I push the results back.)

I went ahead and made a very simple Workbench which demonstrates my JSON and the problem. 

Could someone help with either solution or maybe something else I didn’t think about?

Ignore this comment


You could use xquery to get the position and use the attribute in the JSON updater?

So XMLXQueryExtractor

 

let $json_doc := fme:get-json-attribute("NE_JSON")
let $processors := jn:members($json_doc("flowContents")("processors"))
return (
fn:index-of($processors("name"),"Build-Parameters")
)

Then use the created attribute containing the index in the JSONPath in the JSON Updater

 

 

I suspect you could do the entire replacement using XMLXqueryUpdater


ebygomm, I went ahead and marked your answer as the best answer. I think you are correct and this could all be accomplished in XMLXqueryUpdater. 

I did have a few reasons I had chosen JSONUpdater. 1. I really liked the JSONUpdater dialog box for listing the individual changes to the document. Makes it easier for someone after me to see everything that I was changing. 2. I’m not good at Xquery (or JSONIq hence post), but going back to #1 and trying to find JSONiq solution seemed to fit using JSONUpdater. 3. I did initially solve this with simple AttributeManager and doing sting replace for values. But it started becoming complex as I couldn’t control all the values I was trying to replace. So moved to using JSONUpdater. 

In the end I liked the JSONUpdater dialog box so much I wrote a very simple Python script to sort order the processors by name. Then I could always reference the order number. 

self.data = json.loads(feature.getAttribute('NIFI_JSON_TEMPLATE'))
processors = self.data.get("flowContents", {}).get("processors", [])
sorted_processors = sorted(processors, key=lambda x: x.get("name", ""))
self.data["flowContents"]["processors"] = sorted_processors
feature.setAttribute("NIFI_JSON_TEMPLATE", json.dumps(self.data, indent=2))
self.pyoutput(feature)

 


Sorting the json with python sounds more complex and less supportable to me than getting the position with xquery and then using that as the index in the JSON Updater but glad you got it sorted.