Search code examples
xmlsplitdataweavemulesoft

Mulesoft 3 DataWeave - split a string by an arbitrary length


In Mule 3 DataWeave, how do I split a long string into multiple lines by a set length?

For instance, I have the following JSON input:

{
   "id" : "123",
   "text" : "There is no strife, no prejudice, no national conflict in outer space as yet. Its hazards are hostile to us all. Its conquest deserves the best of all mankind, and its opportunity for peaceful cooperation many never come again."
}

The input system can only accept strings of 40 characters or less, so the output XML needs to conform as follows:

<data>
   <id>123</id>
   <text>
      <line>There is no strife, no prejudice, no nat</line>
      <line>ional conflict in outer space as yet. It</line>
      <line>s hazards are hostile to us all. Its con</line>
      <line>quest deserves the best of all mankind, </line>
      <line>and its opportunity for peaceful coopera</line>
      <line>tion many never come again.</line>
   </text>
</data>

I know splitBy can use a delimiter, but I want to use an arbitrary length.


Solution

  • Try this Tony:

    %dw 1.0
    %output application/xml
    %var data = {
       "id" : "123",
       "text" : "There is no strife, no prejudice, no national conflict in outer space as yet. Its hazards are hostile to us all. Its conquest deserves the best of all mankind, and its opportunity for peaceful cooperation many never come again."
    }
    ---
    data: {
        id: data.id,
        text: data.text scan /.{1,40}/ reduce (
            (e,acc={}) -> acc ++ {text: e[0]}
        ) 
    }
    

    I don't know of any way to dynamically inject range values in a regular expression in DW 1.0 (I have yet to check but I bet it is possible in DW 2.0). As such I wrote a DW 1.0 function do break in equal parts a :string value. Here's the transformation that know you should be able to dynamically set the size:

    %dw 1.0
    %output application/xml
    %var data = {
       "id" : "123",
       "text" : "There is no strife, no prejudice, no national conflict in outer space as yet. Its hazards are hostile to us all. Its conquest deserves the best of all mankind, and its opportunity for peaceful cooperation many never come again."
    }
    
    %function equalParts(str,sz)
        [str]
        when ((sizeOf str) < sz or sz <= 0) 
        otherwise
            using (
                partCoords = (0 to (floor (sizeOf str) / sz) - 1) map [$ * sz, $ * sz + sz - 1] 
            ) (
                
                partCoords + [partCoords[-1][-1]+1,-1] map 
                    str[$[0] to $[1]]
            )
    
    ---
    data: {
        id: data.id,
        text: equalParts(data.text,40) reduce (
            (e, acc={}) -> acc ++ {text: e}
        )
    }