File Adapter - Multiple Elements

File Adapter - Multiple Elements

This section deals with the cases when the format of the data you wish to store contains multiple elements, thus when you are saving them it would be more helpful to save all of the elements, for those who have completed the oracle fusion course, within each PurchaseOrder there can be multiple instances of the Item element, however, if you use the simple 1 to 1 mapping specified in the tutorial, only the first item will be captured and saved, this guide will explain how to set up the BPEL to capture all elements.

In order to convert the File Adapter to do this, no actual changes to the file adapter is required, however some of the related files need to be modified, each of these files and the changes are listed below:

XML Schema of The File Adapter

Fild the schema of the File Adapter that you are using, to do this, first open up the File Adapter from the BPEL by double clicking on this, this will bring up the Edit screen for the File Adapter, simply look at the WSDL File field of the WSDL Settings section to get a complete path to the WSDL file for this File Adapter, within the WSDL file, find the "schema" element, this element should have a schemaLocation property which specifies (relative path) the location of the schema file (XSD).

Open the XSD and view the Source (note that this is the most direct way of doing this, be very careful when doing modifications within the Source view, as slight spelling mistakes makes a big difference), you will see the setup that was set up when creating the File Adapter as per the tutorial, which would look like this:

<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:nxsd="http://xmlns.oracle.com/pcbpel/nxsd"
            targetNamespace="http://www.globalcompany.com/ns/order"
            xmlns:tns="http://www.globalcompany.com/ns/order"
            elementFormDefault="qualified" attributeFormDefault="unqualified"
            nxsd:encoding="ASCII" nxsd:stream="chars" nxsd:version="NXSD">
  <xsd:element name="filecontent">
          <xsd:complexType>
            <xsd:sequence>
              <xsd:element name="firstname" type="xsd:string"
                           nxsd:style="terminated" nxsd:terminatedBy=" "
                           nxsd:quotedBy='"'></xsd:element>
              <xsd:element name="lastname" type="xsd:string"
                           nxsd:style="terminated" nxsd:terminatedBy=" "
                           nxsd:quotedBy='"'></xsd:element>
              <xsd:element name="product" type="xsd:string"
                           nxsd:style="terminated" nxsd:terminatedBy="${eol}"
                           nxsd:quotedBy='"'></xsd:element>
            </xsd:sequence>
          </xsd:complexType>
  </xsd:element>
</xsd:schema>

The desired target of this modification is to get it so that the schema allows multiple instances of the filecontent element, to do this you will have to encapsulate all of the elements you want to become iterative by specifying an unbounded max occurance property, however, the current structure does not accomodate this kind of change directly (by adding the unbounded property to the filecontent element), so to do this, we encapsulate the contents of filecontent within another sequence, which I have given the name "order", the new modified xml would now look like:

<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:nxsd="http://xmlns.oracle.com/pcbpel/nxsd"
            targetNamespace="http://www.globalcompany.com/ns/order"
            xmlns:tns="http://www.globalcompany.com/ns/order"
            elementFormDefault="qualified" attributeFormDefault="unqualified"
            nxsd:encoding="ASCII" nxsd:stream="chars" nxsd:version="NXSD">
  <xsd:element name="filecontent">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="order">
          <xsd:complexType>
            <xsd:sequence>
              <xsd:element name="firstname" type="xsd:string"
                           nxsd:style="terminated" nxsd:terminatedBy=" "
                           nxsd:quotedBy='"'></xsd:element>
              <xsd:element name="lastname" type="xsd:string"
                           nxsd:style="terminated" nxsd:terminatedBy=" "
                           nxsd:quotedBy='"'></xsd:element>
              <xsd:element name="product" type="xsd:string"
                           nxsd:style="terminated" nxsd:terminatedBy="${eol}"
                           nxsd:quotedBy='"'></xsd:element>
            </xsd:sequence>
          </xsd:complexType>
        </xsd:element>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

Now the structure of the filecontent has changed from containing 3 string elements to containing a seqeuence of order elements, from here we can simply set the order element to allow multiple occurances, to do this we just have to specify 2 properties for the order element by appending the following to the declaration of the order element:

maxOccurs="unbounded"

By default, the minOccurs is set to 1 and the maxOccurs is set to 1, minOccurs determines the minimum occurances of the element, meaning that if it is set to 1, there must be at least one element of that type, if it is 0, the element is not required, maxOccurances just states what is the maximum number of occurances, when set to 1, there can only be a single element of that type, in our case, we want the parameter to be set to "unbounded", doing so will make it so that there can be an infinite number of occurances of the element.

<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:nxsd="http://xmlns.oracle.com/pcbpel/nxsd"
            targetNamespace="http://www.globalcompany.com/ns/order"
            xmlns:tns="http://www.globalcompany.com/ns/order"
            elementFormDefault="qualified" attributeFormDefault="unqualified"
            nxsd:encoding="ASCII" nxsd:stream="chars" nxsd:version="NXSD">
  <xsd:element name="filecontent">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="order" maxOccurs="unbounded">
          <xsd:complexType>
            <xsd:sequence>
              <xsd:element name="firstname" type="xsd:string"
                           nxsd:style="terminated" nxsd:terminatedBy=" "
                           nxsd:quotedBy='"'></xsd:element>
              <xsd:element name="lastname" type="xsd:string"
                           nxsd:style="terminated" nxsd:terminatedBy=" "
                           nxsd:quotedBy='"'></xsd:element>
              <xsd:element name="product" type="xsd:string"
                           nxsd:style="terminated" nxsd:terminatedBy="${eol}"
                           nxsd:quotedBy='"'></xsd:element>
            </xsd:sequence>
          </xsd:complexType>
        </xsd:element>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

Once the property has been added, go to the Design view and you should be able to see something similar to the screenshot below.

Notice that for the link between filecontent and order there is a brief notation saying one to infinity, this basically specifies that within each filecontent, there must be at least 1 order and can contain up to an infinite number of orders, each order contains the 3 string elements that we required for the File Adapter.

XSL Transformation File

The next step is to change the Transformation for 2 reasons, first one is that because we have made significant structural changes to the schema of the File Adapter, the current Transformation is no longer valid, and the old Transformation does not handle multiple occurances.

The simplest way to do this is to open up the Transformation file (double click on the Transformation Process Activity and then click the pencil icon next to the Mapper File field within the Mapper Configuration section), right click within the Transformation file either in the Source section or the Target section and choose Replace Schema... then find the source schema and target Schema again, for our example, the source schema would be located under Project WSDL Files -> SOAOrderBooking.wsdl -> Inline Schemas -> schema -> SOAOrderBookingProcessRequest, the target will be under Project WSDL Files -> <name of your file writer>.wsdl -> Inline Schemas -> schema -> filecontent. Upon accepting the new schemas, you will be prompted with a warning saying that the current mapping will be cleared, just accept this.

Like before, recreate the mappings between the different fields (eg firstname, lastname and product), then after this is done, go to the Component Palette and select XSLT Constructs, this will bring up a new set of functions, the one we are interested in is the "for-each" function, drag the "for-each" function onto your target, and place it on top of your order element (or whichever element you gave the unbounded maxOccurs property for), this will embed the "for-each" function within your Transformation, now go to the source and find the element that you wish to iterate through, and drag it across to the "for-each" node that you just added, the result will look something like this:

The logical way to express this mapping would be:
For each occurance of Item within the SOAOrderBookingRequest, copy across the first name, last name and product name across to the target schema.
Using this transformation, if an order booking request contains more than 1 item, then the FileAdapter will place 1 entry in the file for each item contained.

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.