Search code examples
mulemule-studiomule-el

Extracting array from JSON in mule esb


I'm using Mule 3.4 CE and I have a JSON data coming through HTTP in the following format:

{
   "People" : [
    {
       "Details" : 
       {
         "Name" : "John Smith",
         "Email" : "abc@mail.com"
       }
    },
    {
       "Details" : 
       {
         "Name" : "Tim Smith",
         "Email" : "def@mail.com"
       }
    },
    {
       "Details" : 
       {
         "Name" : "Ken Smith",
         "Email" : "ghi@mail.com"
       }
    },
}

I need to extract the emails and lookup the Salesforce contact with these emails and at the same time I want to retain the JSON payload. So my question is how do I extract the emails through MEL? (for e.g. something like "People/Details/*/Email" - I know this is not a valid, but I'm looking for the right syntax.

Edit: I want to extract the emails in one shot rather than indexing (for e.g. People/Details[0].Email, possibly using MEL.


Solution

  • There best way to query json is to transform it to a Map.

    <json:json-to-object-transformer returnClass="java.util.HashMap" />
    

    And then query it using MEL like standard MVEL or Java syntax

    <logger message="#[payload.People[0].Details.email]" level="INFO" />
    

    If you want to keep the original json payload intact, you can store the map in a variable using an enricher:

    <enricher target="#[flowVars.myJsonMap]">
       <json:json-to-object-transformer returnClass="java.util.HashMap" />
    </enricher>
    

    And query the variable instead of the payload:

    <logger message="#[flowVars.myJsonMap.People[0].Details.email]" level="INFO" />
    

    You could also map the json to a custom class using Jackson and change the returnClass attribute to your class.

    This MEL cheat sheet detail JSON processing with MEL and also how to handle Maps, arrays etc: http://www.mulesoft.org/documentation/display/current/MEL+Cheat+Sheet

    Note: You may come across a #[json:] evaluator, but this is deprecated in favour of the approach above.

    UPDATE:

    If you want to grab all the emails at once you can use MVEL projections:

    <enricher target="#[flowVars.myJsonMap]" source="#[(Details.email in payload.People)]">
           <json:json-to-object-transformer returnClass="java.util.HashMap" />
    
        </enricher>
    

    Mvel projections: http://mvel.codehaus.org/MVEL+2.0+Projections+and+Folds