Showing posts with label Oracle BPEL 11g. Show all posts
Showing posts with label Oracle BPEL 11g. Show all posts

Sunday, August 4, 2013

XPath query string returns zero node. The assign activity of the to node query is returning zero node. Either the to node data or the xpath query in the to node was invalid

XPath query string returns zero node. The assign activity of the to node query is returning zero node. Either the to node data or the xpath query in the to node was invalid

Very common error and we are sure, every developer must have seen this.
Normally we get this error when we are looping over a variable and mapping to a target variable. In first loop, assign operation is successful and then we get the above error when loop runs for the second time.

To resolve this, we use append option while assigning the variable
But if there are more than one variables to be assigned, then there are 2 ways:

One option is to create a temp variable of output type and complete the assignment and then in the end, map it to the output using assign and append option. But this method has an overhead of temp variable.

Second option which we are going to explain is what we recommend. It doesn’t require any temp variable to be managed and is lot easier!!!

We will begin with the below example wherein we are building a basic calculator.

The sample xsd which we have used is below:


Input:

  <ns1:calcInput>
    <ns1:input>
     <ns1:number1>1</ns1:number1>
     <ns1:number2>1</ns1:number2>
     <ns1:operation>add</ns1:operation>
    </ns1:input>
    <ns1:input>
     <ns1:number1>1</ns1:number1>
     <ns1:number2>3</ns1:number2>
     <ns1:operation>add</ns1:operation>
    </ns1:input>
    <ns1:input>
     <ns1:number1>1</ns1:number1>
     <ns1:number2>4</ns1:number2>
     <ns1:operation>add</ns1:operation>
    </ns1:input>
   </ns1:calcInput>

Output:

<result>
  <output>
   <number1>1</number1>
   <number2>4</number2>
   <operation>add</operation>
   <result>5</result>
  </output>
  <output>
   <number1>1</number1>
   <number2>1</number2>
   <operation>add</operation>
   <result>2</result>
  </output>
  <output>
   <number1>1</number1>
   <number2>3</number2>
   <operation>add</operation>
   <result>4</result>
  </output>
  <output>
   <number1>1</number1>
   <number2>1</number2>
   <operation>add</operation>
   <result>2</result>
  </output>
 </result>           

The flow of the code looks something as shown below:


First loop in the code will do a normal mapping and the operation using the loopCounter variable






Second time, the flow goes in otherwise wherein we append the output variable to the output variable itself as shown below:



After that, we assign the input variable to the output but using loopCounter variable at the input and index 1 on the output side as shown below:


That’s it and you should get the output as expected.

I have the sample code with me. Email us if you need the sample. 

Thanks and Happy Coding J J J

Cheers,
LetsLearnOracleSOA Team

Sunday, July 28, 2013

Compare two collections or xmls and set value in output using xsl/transformation

We come across situations wherein we need to compare some elements from two collection and generate the output
I would like to explain the solution using the example:
Input1 contains list of employees and their current salary and Input2 contains the increment percentage for the employees.
Now input2 might not contain all the employees, so for those missing employees, the increment is default which is 5%
We need to calculate the new salary for all the employees from input1
Sample inputs are as below:

Input1:


<EmployeeDetails>
      <employeeid>1</employeeid>
      <employeename>employeename10</employeename>
      <salary>1000</salary>
   </EmployeeDetails>
   <EmployeeDetails>
      <employeeid>2</employeeid>
      <employeename>employeename12</employeename>
      <salary>10000</salary>
   </EmployeeDetails>
   <EmployeeDetails>
      <employeeid>3</employeeid>
      <employeename>employeename14</employeename>
      <salary>1500</salary>
   </EmployeeDetails>

Input2:


<IncrementDetails>
      <employeeid>1</employeeid>
      <incrementPercentage>10</incrementPercentage>
   </IncrementDetails>
   <IncrementDetails>
      <employeeid>2</employeeid>
      <incrementPercentage>20</incrementPercentage>
   </IncrementDetails>

Expected output:


<output xmlns:client="http://xmlns.oracle.com/CopyTables/LoopTwoNodes/LoopTwoNodesBPEL" xmlns="http://xmlns.oracle.com/CopyTables/LoopTwoNodes/LoopTwoNodesBPEL">
         <client:output>
            <client:employeeid>1</client:employeeid>
            <client:employeename>employeename10</client:employeename>
            <client:salary>1100</client:salary>
            <client:comment>Congratulation!! Your increment percentage is 10</client:comment>
         </client:output>
         <client:output>
            <client:employeeid>2</client:employeeid>
            <client:employeename>employeename12</client:employeename>
            <client:salary>12000</client:salary>
            <client:comment>Congratulation!! Your increment percentage is 20</client:comment>
         </client:output>
         <client:output>
            <client:employeeid>3</client:employeeid>
            <client:employeename>employeename14</client:employeename>
            <client:salary>1575</client:salary>
            <client:comment>Default increment</client:comment>
         </client:output>
      </output>

xsl/Transformation to achieve this looks like below:


<xsl:param name="input2"/>
  <xsl:template match="/">
    <client:output>
      <xsl:for-each select="/client:input1/client:EmployeeDetails">
        <xsl:variable name="loopvar" select="position()"/>
        <xsl:choose>
          <xsl:when test='contains(oraext:create-delimited-string($input2/client:input2/client:IncrementDetails/client:employeeid,","),client:employeeid)'>
            <xsl:for-each select="$input2/client:input2/client:IncrementDetails">
              <xsl:if test="client:employeeid = /client:input1/client:EmployeeDetails[$loopvar]/client:employeeid">
                <client:output>
                  <client:employeeid>
                    <xsl:value-of select="/client:input1/client:EmployeeDetails[$loopvar]/client:employeeid"/>
                  </client:employeeid>
                  <client:employeename>
                    <xsl:value-of select="/client:input1/client:EmployeeDetails[$loopvar]/client:employeename"/>
                  </client:employeename>
                  <client:salary>
                    <xsl:value-of select="/client:input1/client:EmployeeDetails[$loopvar]/client:salary + (/client:input1/client:EmployeeDetails[$loopvar]/client:salary * (client:incrementPercentage div 100.0))"/>
                  </client:salary>
                  <client:comment>
                    <xsl:value-of select='concat("Congratulation!! Your increment percentage is ", client:incrementPercentage)'/>
                  </client:comment>
                </client:output>
              </xsl:if>
            </xsl:for-each>
          </xsl:when>
          <xsl:otherwise>
            <client:output>
              <client:employeeid>
                <xsl:value-of select="client:employeeid"/>
              </client:employeeid>
              <client:employeename>
                <xsl:value-of select="client:employeename"/>
              </client:employeename>
              <client:salary>
                <xsl:value-of select="/client:input1/client:EmployeeDetails[$loopvar]/client:salary + (/client:input1/client:EmployeeDetails[$loopvar]/client:salary * (5.0 div 100.0))"/>
              </client:salary>
              <client:comment>
                <xsl:text disable-output-escaping="no">Default increment</xsl:text>
              </client:comment>
            </client:output>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:for-each>
    </client:output>
  </xsl:template>


Happy Coding J

Cheers,

LetsLearnOracleSOA Team

Saturday, July 13, 2013

Validate XML schema In BPEL

Hello Friends,

Many time we came across the situation where we need to validate our input based on the schema before doing any processing on the received input.

Oracle BPEL provides 3 ways to do validation.

One way is to use Validate Activity and the second is by enabling Validate option in Assign/Transform activity and third way is Payload Validation on EM Console. Later in this Blog we will explain the implementation details.
 
Implementation of Validate Activity:
This activity enables you to validate variables in the list. The variables are validated against their XML schema.

[Note] : In BPEL 2.0, the Validate dialog includes a Documentation tab, Targets tab, and Sources tab, and does not include a Skip Condition tab

Steps to Implement:

1.     Create a BPEL process (For the Demo purpose below mentioned schema has been used to validate)




2.     From the BPEL Constructs section of the Component Palette, drag a Validate activity into the designer.
[Note]: In BPEL 1.1 Validate activity is not displayed in BPEL Constructs drop down menu. It needs to be added on source code (Mentioned in step 4).



3.     Double-click the Validate and Enter a name for the activity. Add the variable which needs to be validated.




4.     Click the Source tab to view the syntax. Note that the syntax for validating XML data with the validate activity is slightly different between BPEL versions 1.1 and 2.0.

                       <validate name="Validate_XMLSchema" variables="inputVariable"/> (For BPEL 2.0)

                       <bpelx:validate variables="inputVariable" name="Validate_XMLSchema"/> (For BPEL 1.1)

5.     Deploy to server.
6.     As mentioned in the XSD (step 1) we have put constraint of length 8 to field CompanyName. To Check the validation we will have 9 charaters for CompanyName
                  
                       Input:

                      <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
                            <soap:Body>
                               <ns1:process xmlns:ns1="http://xmlns.oracle.com/Demo/DemoValidateActivity">
                                       <ns1:CompanyName>123456789</ns1:CompanyName>
                                       <ns1:CompanyID>12345</ns1:CompanyID>
                              </ns1:process>
                           </soap:Body>
                        </soap:Envelope>

                      Output:

                         




Implementation of Assign Activity with validate option enabled:

Steps to implement:

1.      From the BPEL Constructs section of the Component Palette, drag an Assign activity into the designer.
2.      Double-click the Assign activity.
3.      In the General tab, enter a name for the activity and select the Validate checkbox.

                        


4.      Click Apply, then OK.
5.      Click the Source tab to view the syntax. Note that the syntax for validating XML data with the assign activity is slightly different between BPEL versions 1.1 and 2.0.
<assign name="Assign_ValidateXML" validate="yes"/> (For BPEL 2.0)
<assign name="Validate_XMLSchema" bpelx:validate="yes"/> (For BPEL 1.1)
 
6.      Deploy to server
 

 Implementation of Payload Validation:

          1.     Login to EM Console and go to the composite for which Payload validation is needed. Go to settings -> Payload Validation and select option Enable.                                                                                              
 
2.       Schema validation failed then an error is thrown :
 
                                        
                3.      Fault Message :
                                        
 
 
 
Cheers,
Lets Learn Oracle SOA Team