'Add an XML fragment to existing XML payload in BPEL process

My current payload XML from BPEL looks like,

<Parent>
<child1>
<key>K1</key>
<value>V1<value>
</child1>
<child1>
<key>K11</key>
<value>V11<value>
</child1>
<child2>
<key>K2</key>
<value>V2<value>
</child2>
</Parent>

I want to add a new fragment of child1 into the existing XML payload so that the output looks as follows,

<Parent>
<child1>
<key>K1</key>
<value>V1<value>
</child1>
<child1>
<key>K11</key>
<value>V11<value>
</child1>
<child1>
<key>K12</key>
<value>V12<value>
</child1>
<child2>
<key>K2</key>
<value>V2<value>
</child2>
</Parent>

I googled and found that bpelx:append method can help in inserting the xml fragment. But I still can't figure out how to first create/store a new fragment in a String/xml data type so that it can be passed to the existing payload.

Any pointers or help would be much appreciated.



Solution 1:[1]

To begin with: The XML snippets you posted are not well-formed, since you are using opening tags at various positions where closing tags should be.

Second, the bpelx:append function is not part of BPEL, but a proprietary extension from Oracle (which I guess you are using). You can find documentation on this function, as well as others that might be useful to you here. Third, you do this transformation in an XPath expression in an assign activity.

Now, to your actual question:

I still can't figure out how to first create/store a new fragment in a String/xml data type so that it can be passed to the existing payload.

That largely depends on where you want to get that data from. Is it hard-coded in the process? Or does it come from a message you received?

Disclaimer: Since I don't have an instance of Oracle SOA Suite installed, I have not tested these code fragments.

If it is hard-coded, you can just put it in a literal block:

<bpel:assign>
    <bpelx:append>
          <from>
               <literal>
                      <child1>....</child1>
               </literal>  
          </from>
          <to variable="variableWithYourPayload"
                query="/your-ns:Parent" />
    </bpelx:append> 
</bpel:assign>

If it is comes from a message you received, then you should have stored the message in a variable from which you can read:

<bpel:assign>
    <bpelx:append>
          <from variable="inputMessageWithChild1Content" />
          <to variable="consolidatedBillOfMaterialVar"
                query="/your-ns:Parent" />
    </bpelx:append> 
</bpel:assign>

You can also always just create a variable of the XML type. However that requires that the XML type is defined somewhere in the WSDL or XSD files you import, which normally should be the case. This should look somehow like this:

<variable name = "myVar" type="myNs:child1" />
<!-- more process code -->
<bpel:assign>
          <from>
               <literal>
                      <child1>....</child1>
               </literal>  
          </from>
          <to variable="myVar" />
</bpel:assign>

Afterwards, you can use this variable in an append just like in the second snippet.

Solution 2:[2]

I was getting a compilation error for <literal> and realized that I had to use namespace with it. Once I switched it to <bpel:literal> I was able to compile and deploy without any issues. Just make sure you are using the correct name space.

<variable name = "myVar" type="myNs:child1" /> <!-- more process code
--> <bpelx:assign>
          <from>
               <bpel:literal>
                      <child1>....</child1>
               </bpel:literal>  
          </bpelx:from>
          <to variable="myVar" />
    </bpel:assign>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 joergl
Solution 2 Sid