Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Mule 3.8 DataWeave Read for Lists MIME Type

DZone's Guide to

Mule 3.8 DataWeave Read for Lists MIME Type

Learn how a read sentence in DataWeave can save you time and effort in Mule 3.8.

· Integration Zone
Free Resource

Share, secure, distribute, control, and monetize your APIs with the platform built with performance, time-to-value, and growth in mind. Free 90 day trial 3Scale by Red Hat

Recently, I was faced with a problem while trying to apply a reduce operation on a list of XML strings; I was running Mule 3.7, and after more attempts than I care to remember, I had to adopt an overkilling workaround. Meanwhile, with Mule 3.8, there's a very simplye way to solve the problem.

Let's jump into the case: A Mule flows reads, once a day, from a repository where objects created and saved the day before are placed. Suppose our domain object is an order containing one or more books. The order is stored as an XML string:


<order>
    <book>Title1</book>
    <book>Title2</book>
</order>


After the read operation, the payload is a list of XML strings... but they're still strings!

Suppose we need to sum the number of books of each order to have the total number of books sold. The idea is to use DataWeave and apply map/reduce operators to get the job done. Of course, we need to somehow parse the XML structure of the order. The true story is that in order to parse the XML, you need to set the MIME type of the payload. But our payload is a list, and we need to set the MIME type for each element of the list, not to the list itself.

The only way is to use foreach, set the MIME type, process each order individually, and collect the total number of books in a variable:


<flow name="spikeweavexmlFlow_List_new">
    <set-session-variable variableName="numberOfBooks" value="#[0]" doc:name="NumberOfBooks = 0"/>
        <foreach collection="#[payload]" doc:name="For Each">
        <set-payload value="#[payload]" mimeType="application/xml" doc:name="Set XML mimetype"/>
            <dw:transform-message doc:name="count books">
            <dw:set-payload>
                <![CDATA[%dw 1.0
                %output application/java
                ---
                {
                    numberOfBooks: sizeOf payload.order.*book
                }]]>
             </dw:set-payload>
         </dw:transform-message>
         <set-session-variable variableName="numberOfBooks" value="#[numberOfBooks + payload.numberOfBooks]" doc:name="Increase NumberOfBooks"/>
    </foreach>
</flow>


A very redundant workaround.

With Mule 3.8, there is a very elegant solution: The read sentence in DataWeave that set the MIME type of the element:


<flow name="dzone-dataweave-readFlow">
    <dw:transform-message doc:name="Transform Message">
        <dw:set-payload>
            <![CDATA[%dw 1.0
            %output application/java
            ---
            numberOfBooks: payload map ({
                numOfBooksPerXml: sizeOf read($,"application/xml").order.*book
            }).numOfBooksPerXml reduce $$ + $]]>
        </dw:set-payload>
    </dw:transform-message>
</flow>


Basically, in the map operator, the value variable $ is now an XML element we can parse and have access to.

Discover how you can achielve enterpriese agility with microservices and API management

Topics:
mule 3.7 ,mule esb ,muleesb

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}