Created 08-31-2020 07:15 AM
Currently I am having around 15 attributes in my flowfile. Out of these 15, i only want a few (all the attributes that have a prefix 'error_' in it. These 'error_*' attributes can have 2 sets of values, eighter- 'valid' or some error code, say- '945'. Now i want to iterate though all the attributes with prefix - 'error_' and if its value is 'valid', do nothing and if its value is having some error code, append the error code to a string separated by ';'. So basically, if I have 5 error_ attributes:
error_field1: '123' error_field2: 'Valid' error_field3: '567' error_field4: 'Valid' error_field5: '45'
I want my output as - '123;567;45'.
Please help me as i am new to Nifi and i am not sure on how to work with such complex EL.
Created on 08-31-2020 11:42 PM - edited 08-31-2020 11:42 PM
Sorry, I can't give you a perfect solution but maybe a hint to find one.
Just do GenerateFlowFile and set your attributes like in your example.
Then take UpdateAttribute and play around with Expression Language possibilities like "anyMatchingAttribute" or "allMatchingAttribute" maybe in combination with "join".
Have a look in the documentation here
https://nifi.apache.org/docs/nifi-docs/html/expression-language-guide.html#multi
Created 09-30-2020 10:34 AM
Hi @Nidutt! Use the below Expression Language:
${literal(${allMatchingAttributes("error_field.*"):join(";")}):replaceAll('Valid|;',' '):trim():replaceAll('\s+',';')}
Created 10-02-2020 02:11 AM
Great solution! I was sure it has to be possible but couldn't find out how...
Just for my understanding:
First all attributes name starting with error_field getting joined and then you replace the value 'Valid' with space and removing this by the last replaceAll.
But what is the meaning of | here: replaceAll('Valid|;',' ')
Without | the result is 123;;567;45 but why not 123;;567;;45
Thanks in advance for reply.
Created 10-02-2020 10:33 AM
If you consider various use cases,
1)Consider the input 123;Valid;567;45. The first replace method ( replaceAll('Valid',';') ) will give 123; ;567;45 which on applying the next replace method ( replaceAll(' ',';') ) will give 123;;567;45. This is not the desired output.
2)Consider another input Valid;123;567;Valid;Valid;45. First replace method will give ;123;567; ; ;45
Second replace method will give ;;123;567;;;45. Again, this is not the desired output.
To remove all the confusion, what I wanted to do was, separate all the values other than "Valid" with empty spaces. So, I replaced Valid and ; with empty spaces.
But, there might be cases where there are empty spaces at the beginning or at the end ( ( 123 567 45) or (123 567 45 )). So, I used trim method to remove outer spaces. Then, you will be left with values other than "Valid" separated by spaces (can be more than 1). So, now, the second replace method will just add one semi-colon, irrespective of the number of spaces between. So, the output will be 123;567;45.
Hence, the regex Valid|; will replace both "Valid" and semi-colons.
Created 10-05-2020 12:10 AM
OK, it covers possible alternative cases.
Got it! Thanks for this explanation.