Explanation of $ in Mule MEL - mule

I cannot find any documentation around the use of $ in MEL other than a couple of lines here
You can refer to any Java class by its fully qualified name or if it
is one of the classes in the automatically-imported Java classes, by
its unqualified name. References use the same dot notation as in Java,
except that you must use $ rather than a dot to refer to a nested
class.
I can find a couple of examples here
JSON processing MEL has no direct support for JSON. The
json-to-object-transformer can turn a JSON payload into a hierarchy of
simple data structures that are easily parsed with MEL. For example,
the following uses a filtered projection to build the equivalent of
the
$..[?
(#.title=='Moby Dick')].price JSON path expression:
<json:json-to-object-transformer returnClass="java.lang.Object" />
<expression-transformer
expression="#[($.price in message.payload if $.title == 'Moby Dick')[0]]" />
I want to understand in which cases does the $ get used...

$ comes from MVEL, the language underlying MEL.
$ serves as the placeholder for the element being filtered. It is
actually a regular variable that exists inside the context of the
projection. You can also use it to return the current element in the
projection to the representative list.
Reference: http://mvel.codehaus.org/MVEL+2.0+Projections+and+Folds#MVEL2.0ProjectionsandFolds-Filters

Related

Getting error "unbalanced braces" in data weave in mule 3.9.3

I am using choice router to evalute expression. Here is the expression
and I tested this expression in dataweave here is the result.
but when I use the choice router to evalute the expression I am getting this result
and another thing the value of "payload.relations.rel" is "Microsoft.VSTS.Common.TestedBy-Reverse" why I am getting false for this expression
bench : payload.relations.rel == "Microsoft.VSTS.Common.TestedBy-Reverse"
The error is not from DataWeave. In Mule 3.x the expression language used is MEL (Mule Expression Language). DataWeave is only used in Transform components. This is different from Mule 4.x where DataWeave 2 is used as the expression language. Testing the expression of the choice in DataWeave is not a good test.
Also your tests show that you are comparing an array (payload.relations.rel) to a String. Try fixing the comparison first. Then if you still have the error try putting it into a logger component before the choice and see if it prints the right result.

what are the various ways to fetch the properties from payload?

What is the difference between reading the properties from payload. for example there is a property in the payload which is named as con_id. when i read this property like this #[payload.con_id] then it is coming as null. where as #[payload.'con_id'] is returning the value.
few other notations which i know of is #[payload['con_id']] or #[json:con_id]
which one should be used at which scenario? if there are any special cases to use any specific notation then please let me know the scenario also.
Also, what is the common notation that has to be used from a mule soft platform supported point of view.
In Mule 3 any of those syntax are valid. Except the json: evaluator is for querying json documents where as the others are for querying maps/objects. Also the json: evaluator is deprecated in Mule 3 in favor of transforming to a map and using the MEL expressions below.
payload.property
payload.'property'
payload['property']
The reason the first fails in your case, is beacaue of the special character '_'. The underscore forces the field name to be wrapped in quotes.
Typically the . notation is preferred over the [''] as its shorter for accessing map fields. And then simply wrap property names in '' for any fields with special chars.
Note in Mule 4, you don't need to transform to a map/object first. Dataweave expression replace MEL as the expression language and allow you to directly query json or any type of payload without transforming to a map first.

Access FlowVar dynamically in DataWeave

I'm trying to access a FlowVar name dynamically in DataWeave.
For example:
I have a flowVars named taxInfo123. This is a linked list and my applicant.ApplicantID = 123
In my dataweave, I want to access this dynamically. Something like the following:
"TaxInfo": flowVars.'taxInfo'+applicant.ApplicantID map ((taxIdentificationDetail , indexOfTaxIdentificationDetail) -> {
This obviously doesn't work, and I'm hoping this is possible and I just need the correct syntax.
If you need to dynamically create the variable name, you can use the flowVars[key] syntax instead of the flowVars.key syntax. In your scenario:
"TaxInfo": flowVars[('taxInfo' ++ (flowVars.applicant.ApplicantID as :string))]
I assumed applicant was also a flowVar but you could just as easily use payload.applicant.ApplicantID or whatever your situation calls for. I also assumed it was a number so I had to cast it as a string.
When you use this syntax you want to make sure you wrap the key expression in parenthesis so it is evaluated first and then the flowVar is resolved.
So to summarize:
If you know the variable name is 'taxInfo123' -
flowVars.taxInfo123 or flowVars[taxInfo123] are both valid
If you need to create the variable name dynamically -
flowVars[(expression)]
Hope that helps!
Forming the variable name needs append operator like ++. Please go through the MuleSoft documentation for Dataweave operators to get better understanding of how much flexiblity is possible in Dataweave.
https://docs.mulesoft.com/mule-user-guide/v/3.8/dataweave-operators

Simplexml get path from variable

Is there a way to pass the path to a simplexml node as a variable?
This is what I tried:
//set the path to the node in a variable
$comp = 'component->structuredBody->component';
echo count($xml->component->structuredBody->component); //=== 13
echo count($xml->$comp); //===0
echo count($xml->{$comp});//===0
What you need is XPath, and more specifically SimpleXML's xpath() method. Instead of traversing using PHP's -> operator, you would traverse using XPath's / operator, but otherwise, could achieve exactly the effect you wanted:
$comp = 'component[1]/structuredBody[1]/component';
echo count( $xml->xpath($comp) );
You might think that this could be simplified to 'component/structuredBody/component', but that would find all possible paths matching the expression - that is if there are multiple structuredBody elements, it will search all of them. That might actually be useful, but it is not equivalent to $xml->component->structuredBody->component, which is actually shorthand for $xml->component[0]->structuredBody[0]->component.
A few things to note:
Unlike most operations with SimpleXML, the result is an array, not another SimpleXML object (think of it as a set of search results). It is therefore vital that you check it is not empty before accessing element 0 as an object.
As you can see in the example above, XPath counts from 1, not 0. I don't know why, but it's caught me out before, so I thought I'd warn you.
The library SimpleXML is built on supports only XPath 1.0;
examples you see online for XPath 2.0 may not work.
XPath 1.0 has no notion of a "default namespace", and SimpleXML doesn't automatically register namespace prefixes for use in XPath, so if you're working with namespaces, you need to use registerXPathNamespace().

Mule MEL usage difference

I have been using different forms of Mule's Expression language.
I couldn't figure out the difference between
#[flowVars.myVariable]
and
#[flowVars['myVariable']]
They both give the result when there is a variable. But why do they behave differently when the variable is not present?
Like if the variable being called is not available, then the first expression would result in a exception. Whereas the second expression just gives out a warning or prints out as is, if in a logger message.
Why is this difference?
Also when going through the documentation for Mule 3.6 I found that the second expression is not longer shown in the documentation.
Is the expression #[flowVars['myVariable']] being deprecated?
The difference comes from the way MVEL deals with these two different ways of accessing map entries.
#[flowVars['myVariable']] is equivalent to flowVars.get('myVariable'), which does not fail if the flowVars map does not contain the 'myVariable' entry,
#[flowVars.myVariable] treats the flowVars map as a virtual object, leading to an exception if the 'myVariable' entry is missing because in this case it doesn't resolve to a map get but instead to directly using an object member (either a field or a method), which must exist before being accessed.
I don't think #[flowVars['myVariable']] could be deprecated since it's a core feature provided by MVEL.
Reference: http://mvel.codehaus.org/MVEL+2.0+Property+Navigation#MVEL2.0PropertyNavigation-MapAccess
David has given a nice explanation around your question. To extend that explanation I would just like to add that you can use #[flowVars.?myVariable] to make your code null safe. This is equivalent to #[flowVars['myVariable']].
Regarding #[header:originalFilename], as David said this is not MEL. You can get a list of non-mel expressions which are commonly used in Mule applications in the following link.
http://www.mulesoft.org/documentation/display/current/Non-MEL+Expressions+Configuration+Reference