1
votes

I was trying to create multiple flat XML based on line items from the input XML. Is this possible is just using Dataweave or Datamapper in mule?

Thanks

Please see example above

<?xml version="1.0" encoding="utf-8"?>
<XmlInterchange>
     <InterchangeInfo>
       <Payload>
         <WhsDockets>
            <WhsDocket>
               <Identifier>1</Identifier>
                <DocketDetail>
                </DocketDetail>
                 <DocketLines>
                   <Product>7CAGL3G00</Product>
                   <Description>AGL_7C_0</Description>
                   <QuantityFromClientOrder>7.00</QuantityFromClientOrder>
                   <QuantityActuallyOrdered>7.00</QuantityActuallyOrdered>
                   <ProductUQ>SKD</ProductUQ>
                    <Confirmation>
                         <Lines>
                              <Line>
                               <PartAttribute1>4440_100</PartAttribute1>
                               <PartAttribute2>96489</PartAttribute2>
                               <PartAttribute3>700029611    -   700029710  #4</PartAttribute3>
                               <Quantity>100.000</Quantity>
                               <QuantityUQ>UNT</QuantityUQ>
                               </Line>
                               <Line>
                               <PartAttribute1>4440_100</PartAttribute1>
                               <PartAttribute2>96489</PartAttribute2>
                               <PartAttribute3>700029511    -   700029610 #3</PartAttribute3>
                               <Quantity>100.000</Quantity>
                               <QuantityUQ>UNT</QuantityUQ>
                               </Line>
                         </Lines>   
                    </Confirmation>
                  </DocketLines>
            <WhsDocket>
          <WhsDockets>
       <Payload>
     </InterchangeInfo>
</XmlInterchange>

target

<?xml version="1.0"?><p1:StockMovementDataRequest xmlns:p1="urn:ams.com.au:test:3pl:am:SAP_AM_I_005:StockMovement" xmlns:a="http://www.test.com.au/EnterpriseService/">
<Header>
    <From>warehouse</From>
    <To>client</To>
    <DateTimeStamp>2016-04-13T11:55:30.263+10:00</DateTimeStamp>
</Header>
<StockMovementData>
    <Serialised_Material>YES</Serialised_Material>
    <From_Location>warehouse</From_Location>
    <To_Location>client</To_Location>
    <Material>7CAGL3G00</Material>
    <Serial>700029611   -   700029710 #4</>
    <Quantity>7.00</Quantity>
</StockMovementData>
 <StockMovementData>
    <Serialised_Material>YES</Serialised_Material>
    <From_Location>warehouse</From_Location>
    <To_Location>client</To_Location>
    <Material>7CAGL3G00</Material>
    <Serial>700029511   -   700029610 #3</>
    <Quantity>7.00</Quantity>
</StockMovementData>

or create multiple XML with the line items

1
Can you provide a little more detail? Are you trying to create multiple outbound XML files from a single input?danw
hi danw, yes coming from a complex XML i need the headers to be static but the line items should be dynamic triggering multiple filesPaul D.
Please add some more detail to your question, e.g. some sample input and output. Without that it's going to be difficult to help you find a resolutiondanw
Hi danw, I have updated the questions with the sample XMLs, Any thoughts?Paul D.
The splitting issue appears to be raised and answered in another of your questions already... please close this question if that's the case.danw

1 Answers

0
votes

Single DataWeave transformation can only output one xml file, keep in mind XML can have ONLY ONE ROOT element. DataWeave will also throw error if your transformation is resulting in multiple root elements. So you cannot generate single xml in the format you mentioned in your question. However if you can wrap all that output elements into some root element then you can create that output.

Adding updates to show, how to iterate and generate elements -

We would need to take help of global functions to create a dynamic array of length equal to the quantity ordered -

Add below global function in your mule xml -

<configuration doc:name="Configuration">
     <expression-language>
         <global-functions>

            def getArrayOfLength(value){
                int i = 0;
                int[] arrRet = [];
                while(i &lt; value){
                    arrRet.add(i);
                    i++;
                }
                return arrRet;
            }   

         </global-functions>
     </expression-language>
 </configuration>

Then we will use this function our dataweave, I am going to use a simple input xml as below and will output name element number of times in -

<?xml version='1.0' encoding='UTF-8'?>
<root>
    <name>Manik</name>
    <times>7</times>
</root>

Then here is the dataweave code -

%dw 1.0
%output application/xml
---
{
  root: {
        (getArrayOfLength(payload.root.times) map ((key,index) -> name: payload.root.name))
    }
}

So what we do is, call our global function by passing in times value eg. 7. This global function will return an array list of number starting from 0 to value-1. Then we use map to loop over this array but we don't have use anything from this array, Instead we can just use our original payload to create the mapping that would be repeated N times in output.

Here is the output -

<?xml version='1.0' encoding='windows-1252'?>
<root>
  <name>Manik</name>
  <name>Manik</name>
  <name>Manik</name>
  <name>Manik</name>
  <name>Manik</name>
  <name>Manik</name>
  <name>Manik</name>
</root>

Hope this gives you an idea of how to do it and helps you to extend it for your use case.