Consider a simple use case. A BPEL process collects quotes from a number of suppliers, to determine which one provides the best price, before submitting an order to that supplier. Typically this will be done using the
BPEL does not support array variables, but we can use XML structures as collections. However, updating a collection to add a new element requires either using a different assignment mechanism ( e.g. XUpdate, not on the roadmap), or performing a copy-append-replace transformation, using XPath 2.0 or XSLT. But the later approach is complicated, obfuscated and fragile.
Instead, we're opting for a simpler mechanism that allows BPEL assignments to both replace and insert content. We introduce an insert
attribute on the
Syntax:
<bpel:assign> <bpel:copy insert="..."?> <bpel:from> ... </bpel:from> <bpel:to> ... </bpel:to> </bpel:copy> </bpel:assign>
The insert attribute can take one of four values:
first
-- The copy/to must select an EII. The value selected by the copy/from is then inserted as the first node inside that EII.last
-- The copy/to must select an EII. The value selected by the copy/from is then inserted as the last node inside that EII.before
-- The copy/to must select an EII or TII. The value selected by the copy/from is then inserted as a node preceding that EII/TII.after
-- The copy/to must select an EII or TII. The value selected by the copy/from is then inserted as a node proceeding that EII/TII.For first
and last
, selectionFailure
. For before
and after
, selectionFailure
. In all four cases, selectionFailure
.
Let $foo be a complex element with value
<foo> <bar1/> <bar2/> </foo>
Performing this assignment,
<bpel:copy insert="last"> <bpel:from> <bpel:literal> <bar3/> </bpel:literal> </bpel:from> <bpel:to> $foo </bpel:to> </bpel:copy>
results in $foo
<foo> <bar1/> <bar2/> <bar3/> <!-- INSERTED --> </foo>
Continuing with the previous value of $foo,
<bpel:copy insert="first"> <bpel:from> <bpel:literal> <bar0/> </bpel:literal> </bpel:from> <bpel:to> $foo </bpel:to> </bpel:copy>
results in $foo
<foo> <bar0/> <!-- INSERTED --> <bar1/> <bar2/> <bar3/> </foo>
Continuing with the previous value of $foo,
<bpel:copy insert="before"> <bpel:from> <bpel:literal> <baz/> </bpel:literal> </bpel:from> <bpel:to> $foo/bar1 </bpel:to> <!-- Insert before "bar1" --> </bpel:copy>
results in $foo
<foo> <bar0/> <baz/> <!-- INSERTED --> <bar1/> <bar2/> <bar3/> </foo>
Continuing with the previous value of $foo,
<bpel:copy insert="before"> <bpel:from> <bpel:literal> <bam/> </bpel:literal> </bpel:from> <bpel:to> $foo/bar2 </bpel:to> <!-- Insert after "bar2" --> </bpel:copy>
results in $foo
<foo> <bar0/> <baz/> <bar1/> <bar2/> <bam/> <!-- INSERTED --> <bar3/> </foo>