Showing posts with label XML Literal. Show all posts
Showing posts with label XML Literal. Show all posts

Friday, July 29, 2016

Learner Series: Handling Dynamic Arrays in SOA 12c (BPEL 2.0)

Dynamic arrays are always tricky to handle within a BPEL process. Every now and then we encounter XML schemas that have generic name-value pair arrays that are unbounded. The challenge is assigning data to and from these dynamic arrays as there are no concrete XML target elements at runtime. Hence, the XML elements must be generated first before assigning values to them.

There are multiple ways this problem can be solved.

For one, you can choose XSLT over a simple assign. XSLT wields more granular control over how the XML elements are handled. You can instruct the XSL processor to loop over dynamic array list and assign values. This of course requires some level of XSLT skill (Although JDeveloper presents an easy XSL mapper, I prefer fiddling with the source) and in certain cases, you may have to pass some BPEL variables (properties) to XSLT in additions to the source and target variables.

Second option would be to use an XML literal (called XML fragment in BPEL 1.1) within your assign activity. Here you can pre-form the XML literal, assign it to the target and then map the values. Not so sophisticated and if you are not careful with namespaces, this could cause a lot of mapping troubles.

Thirdly, with BPEL 2.0 you can simply add an attribute to your copy action in your assign activity to achieve the same. Most simplest of all.

Since this is a learner series, let's get into some details on how to go about this;

Let's first understand the root-cause of the error;

The problem with assigning dynamic arrays within BPEL is that, for the first element in the array, since the XML element is always "available", the copy happens successfully.
However, starting with the second element, all copy rules within assign would fail due to a "selection failure" with the following error because the dynamic array XML elements are still not formed or is empty.

"Exception is thrown because the to-spec at line 140 is evaluated to be empty"
or
"Exception is thrown because the from-spec at line 160 is evaluated to be empty"

depending on whether you are trying to copy to a target or copy from a source.

Your XML schema containing dynamic array may look something like this;



Your typical assign would like the following - you will have to manually let BPEL know which element the values must be mapped - [1], [2], [3] .... [n]. Just append this to your root XML element which contains the dynamic array. In this case;



Now, starting with the second copy rule within your assign, right-click on the rule item and select "ignoreMissingFromData" or "insertMissingToData" depending on whether your dynamic array is being read or written to respectively.



This action would add a flag (attribute) to the copy rule instructing BPEL to handle the dynamic XML element - either ignore or insert.

<copy bpelx:insertMissingToData="yes">
or
<copy bpelx:ignoreMissingFromData="yes">

Happy BPELing...

Monday, July 30, 2012

SOA 11g XML Literal Uninitialized Variable XPath Error

Often while using the XML literal option within a XPath expression builder the following XPath error is encountered at runtime;

<dataObject name="FaultMessage" detailId="55029" isBusinessIndicator="false">
<value> oracle.bpm.bpmn.engine.model.runtime.microinstructions.TrappableException: faultName: {{http://schemas.xmlsoap.org/ws/2003/03/business-process/}uninitializedVariable} messageType: {{http://schemas.oracle.com/bpel/extension}RuntimeFaultMessage} cause: {XPath expression failed to execute. An error occurs while processing the XPath expression; the expression is oraext:parseXML('<Employees><Employee><Name>John Doe</Name><Dept>AE</Dept></Employee><Employee><Name>Cathy Poe</Name><Dept>BES</Dept></Employee></Employees>'). The XPath expression failed to execute; the reason was: internal xpath error. Check the detailed root cause described in the exception message text and verify that the XPath query is correct. }

From the error message although it is clear that the XML literal that is assigned to the XML element is not initialized, the question is how to initialize the XML literal variable?

The following is how the expression builder XML literal assignment looks;



To overcome the initialization issue, we should ensure that the XML fragment/literal that is assigned conforms to the schema along with valid namespace. Namespace declaration is the key here. The XML literal is treated as a variable by the SOA processor and hence would expect the proper namespace for initialization.


Review the XSD (schema) of the target to which you are trying to assign this XML literal. The sample schema used in this example is shown below;


All elements in this 'employees' schema are referenced with the targetNamespace 'http://www.example.com/ns/Employees'. We have to qualify the XML literal elements with this namespace as shown in screenshot below;


This will ensure that the XML literal is successfully initialized and there should be no more 'Uninitialized Variable' errors at runtime.

One other thing which might be of interest with XML literal assignments is that the XML literal should always have a wrapper root element. For example if you have to assign values to the unbounded 'Employee' element as in our example, the XML literal should wrap/enclose all the 'Employee' elements with the 'Employees' root element. Otherwise there will be an error during parsing.