How can customize the conversion of json to xml? - json

I have a JSON object such as { name: "Tyler", age: 10, dogName: "Spot", dogAge: "40" }
Using NiFi, I want to convert it to XMLin a format similar to
<person>
<name>Tyler</tyler>
<age>10</age>
<dog>
<dogName>Spot</dogName>
<dogAge>40</dogAge>
</dog>
</person>
I am using a ConvertRecord processor. I am using JsonTreeReader for the Record Reader and XMLRecordSetWriter for the Record Writer. I am able to read in the JSON just fine. Is there a way to customize XMLRecordSetWriter to be able to output the xml in a specific format? Right now all I can do is turn the above json object into the following:
<name>Tyler</tyler>
<age>10</age>
<dogName>Spot</dogName>
<dogAge>40</dogAge>
It just directly converts JSON to XML. Is there a way to customize this? Is there an alternative to XMLRecordSetWriter that I could use?

Related

Extracting a JSON out of a string using JSONPath

I have Json data as follows:
{
"template" : [
"{
"Id": "abc"
}"
]
}
I am using JSONPath to extract data from the Json above. I would like to extract the "Id" data from the Json using JsonPath.
The problem I see is, the data is being treated as a string and not as a Json as shown below.
"{
"Id": "abc"
}"
If there were no double-quotes I could have used JsonPath as follows:
$.template[0].Id
But due to the double-quotes, I am unable to access the "Id" data. I suspect there is a way to access this data using JsonPath-Expression but I am pretty much a novice here and no amount of research helped me out with a resolution.
How do I treat it as a Json and not as a string using JsonPath? Kindly help me out here.
JSON Path isn't going to be able to parse JSON that's encoded within a string. You need to perform three operations:
Get the string (use JSON Path or something else)
Parse the string as JSON.
Get the data you're looking for on that (JSON Path or something else)

ConvertRecord processor issue with XML to JSON conversion Apache Nifi

I have a requirement where I am converting data from an API to JSON format. The output of the API is initially in XML, so I am using XMLReader controller service to read the XML data, and JSONRecordSetWriter controller service to convert it to JSON format in Apache Nifi 1.9.2.
When I use ConvertRecord processor with the same controller services, my output merely shows the avro schema and not the data expected. I have tried out many options like using AvroSchemaRegistry controller service, but only the schema is seen and null values are passed. Can anyone explain this behavior?
XML flowfile output:
<field1 value="AAAA"/>
<field2 value="BBBB"/>
<field3 value="male"/>
JSON output:
[ {
"field1" : null,
"field2" : null,
"field3" : null
} ]
The documentation specifies that "Records are expected in the second level of XML data, embedded in an enclosing root tag." Your input file appears to be a list of XML tags with no root tag enclosing them.
You could use ReplaceText to wrap the XML in a root tag, then the XMLReader should parse the fields as expected.

How to convert XML to JSON with new JSON structure in Nifi?

I get different XMLs from web services. I want to convert this XML to JSON, but structure must be changed.
For example, I have XML structure like this;
<root>
<A attr="attr1">VAL</A>
<B attr="attr2">VAL</B>
</root>
And result of JSON that I want.
{
"root":{
"Items":[
{
"tag_name":"A",
"attr":"attr1",
"value":"VAL"
},
{
"tag_name":"B",
"attr":"attr2",
"value":"VAL"
}
]
}
}
How can I do this in Nifi? ConvertRecord or UpdateRecord? Also, how should read and write schema for this if record based processors may be used?
You can do it with a pure NiFi flow, the steps to do this are:
Convert the XML to JSON, this can be done with a ValidateRecord processor, you must define the schema of the json, so during this step you are going to check that the input data is ok.
Modify the JSON structure using the JoltTransform processor.

Avro Schema: force to interpret value (map, array) as string

I want to convert JSON to Avro via NiFi. Unfortunately the JSON has complex types as values that I want to see as a simple string!
JSON:
"FLAGS" : {"FLAG" : ["STORED","ACTIVE"]}
How can I tell AVRO to simply store "{"FLAG" : ["STORED","ACTIVE"]}" or "[1,2,3,"X"]" as a string?
Thank you sincerely!
The JSON to Avro conversion performed in NiFi's ConvertJSONToAvro processor does not really do transformation in the same step. There is a very limited ability to transform based on the Avro schema, mostly omitting input data fields in the output. But it won't coerce a complex structure to a string.
Instead, you should do a JSON-to-JSON transformation first, then convert your summarized JSON to Avro. I think what you are looking for is a structure like this:
{
"FLAGS": "{\"FLAG\":[\"STORED\",\"ACTIVE\"]}"
}
NiFi's JoltTransformJSON, ExecuteScript processors are great for this. If your records are simple enough, maybe even a combination of EvaluateJsonPath $.FLAGS and ReplaceText { "FLAGS": "${flags:escapeJson()}" }.

Dojo reading JSON data without an Identifier

I'm trying to parse a JSON from a rest service. This service does not put the data into the format that I think ItemFileReadStore wants, but I cannot change it. Everything I have found in the dojo library for reading JSON data requires an identifier, which my data does not have. This is the JSON data:
{"ChannelReadResponse":[
{"Event": {"#entityOrigin":"System","#entityId":"0x080e00000136ad8986520af104608052","Name":"Untitled","SymbolCode":"OHVPEV---------","TimeObserved":"2012-04-13T21:09:49.207Z","CreatedUser":"Helpdesk","ModifiedUser":"Helpdesk","CreatedTime":"2012-04-13T21:09:49.207Z","ModifiedTime":"2012-04-17T15:51:12.496Z"},
{"#entityOrigin":"System","#entityId":"0x080e00000136bb54ec770af104608028","Name":"My Event","SymbolCode":"OHVPE----------","Severity":"SIGACT","Outcome":"Effective","TimeObserved":"2012-04-16T14:34:29.796Z","CreatedUser":"Helpdesk","ModifiedUser":"Helpdesk","CreatedTime":"2012-04-16T14:34:29.796Z","ModifiedTime":"2012-04-17T15:50:52.499Z"}
]
,"Channel":{"#writable":"false","#connected":"true","#entityId":"0x080e00000136ad8500760af104608064","Name":"Ozone",
"Members":{"Member":[{"#entityOrigin":"System","#entityRef":"0x080e00000136ad8986520af104608052"},{"#entityOrigin":"System","#entityRef":"0x080e00000136bb54ec770af104608028"}]
}}},
{"Event": {"#entityOrigin":"System","#entityId":"0x080e00000136bc3c92d80af104608042","Name":"From2","SymbolCode":"OHVPE----------","TimeObserved":"2012-04-16T19:43:03.150Z","CreatedUser":"Helpdesk","ModifiedUser":"Helpdesk","CreatedTime":"2012-04-16T19:43:03.150Z","ModifiedTime":"2012-04-16T19:43:03.150Z"},
"Channel": {"#writable":"false","#connected":"true","#entityId":"0x080e00000136bc3c92d80af104608034","Name":"Ozone2",
"Members":{"Member":{"#entityOrigin":"System","#entityRef":"0x080e00000136bc3c92d80af104608042"}}}
]}
]}
Is there any way to work with this data? I specifically want all the Events out of it.
Just massage it into the form that the store wants. For example, if you get the data back in a variable called 'data', you could easily just do:
var json = {
identifier: "#entityId",
items: data
};
Then just use the json object in the store.
I can only think of converting your JSON data to JavaScript Object Literal and then add the ID and Name to the JavaScript Object Literal....then convert it into JSON before passing it to your Dojo Store.
I have faced similar issue but i had the luxury to change my service to return JSON with Identifier and Name. I haven't tried what I wrote above.