REST Adapter and JSON Translator in SOA/OSB 12.1.3

April 20, 2015 | 3 minute read
Derek Kam
Consulting Solutions Architect
Text Size 100%:

If you are using the REST adapter in SOA/OSB 12.1.3, you would probably encounter some requirements that you would need to respond with a JSON array format that has no object name or name/value pairs, and must be a valid format according to RFC4627 specification. For example:

["USA","Canada","Brazil","Australia","China","India"]

In SOA/OSB 12.1.3, the REST adapter requires you to design an XML schema in order to generate the proper JSON format you would require. If you want to generate the above JSON format, you would need to understand how the JSON translator works in 12.1.3.

JSON and XML, although different, have some similarities. Hence, JSON constructs can be mapped to XML and vice-versa. The inherent differences between these two formats are handled by following some pre-defined conventions. The convention used in SOA 12.1.3 is based on the BadgerFish convention. Here are some of the rules:

XML JSON Comments
<AccountName>Peter</AccountName> { "AccountName" : "Peter" } XML elements are mapped to JSON object properties
<AccountName isOpen ="true">Peter</AccountName> { "AccountName": {"@isOpen" : true, "$" : "Peter" } } XML attributes are mapped to JSON object properties, with property names starting with @ symbol.  When elements have attributes defined in the XML schema, text nodes are mapped to an object property with the property name $. This is true even if at runtime the attributes do not occur.
<Address>
  <City>San Francisco</City>
</Address>
{"Address" : { "City" : "San Francisco" }} Nested elements become nested objects
<Name>Peter</Name><Name>John</Name> { "Name" : [ "Peter", "John" ] } Elements with maxOccurs > 1 in their schemas (repeating elements) become JSON arrays
<RootElement>
  <Country>USA</Country>
</RootElement>
{ "Country" :  "USA" } XML root elements are dropped when converting to JSON. In the reverse direction, a root element is adding when converting JSON to XML; in such cases the name of the root element is obtained from the schema. This is done because JSON can have multiple top-level object properties which would result in multiple root elements which is not valid in XML.
<Integer>10</Integer>
<String>string-value</String>
<Boolean>true</Boolean>
{"Integer" : 10,"String": "string-value","Boolean": true} The JSON data types - boolean, string and number are supported. When converting XML to JSON, based on the type defined in the XML schema the appropriate JSON type is generated.
<RootElement xmlns="http://xmlns.oracle.com/country">  <Country>USA</Country>
</RootElement>
{ "Country" :  "USA" } The RootElement  and all namespace information (ns declarations and prefixes) are dropped when converting XML to JSON. On converting the JSON back to XML, the namespace information (obtained from the schema) is added back to the XML.
<customers>
 <customer>Peter<customer>      <customer>John<customer>
</customers>
[ "Peter", "John"] Top level arrays - an nxsd annotation nxsd:jsonTopLevelArray="true" can be set in the schema to indicate that the JSON will have a top level array.

 

The following scenarios are not handled by the JSON translator:

  • A choice group with child elements belonging to different namespaces having the same (local) name and a sequence group with child elements having duplicate local names. This is because all namespace information is dropped when converting XML to JSON and translates to a JSON object with duplicate keys, which is not a valid format according to RFC4627 specification. This translates to an object with the duplicate property. For example,

    <productList>
        <products>
            <product>
                <productCode>1</productCode>
                <productDesc>product 1</productDesc>
            </product>
            <product>
                <productCode>2</productCode>
                <productDesc>product 2</productDesc>
            </product>
        </products>
    </productList>
  • Arrays within arrays, for example: [ [ "Harry", "Potter"] , ["Peter", "Pan"]]

  • Mixed arrays, for example:  [ [ "Harry", "Potter"] , "", {"Peter"  : "Pan" }]

  • Handling JSON null

  • XML Schema Instance (xsi) attributes are not supported.

In order to generate the required JSON array format: ["USA","Canada","Brazil","Australia","China","India"], you need to have an XML schema similar to the example as shown below:

<?xml version = '1.0' encoding = 'UTF-8'?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns="http://TargetNamespace.com/ListOfValues_countries_response"
            targetNamespace="http://TargetNamespace.com/ListOfValues_countries_response" 
            elementFormDefault="qualified"
            xmlns:nxsd="http://xmlns.oracle.com/pcbpel/nxsd" 
            nxsd:version="JSON" nxsd:jsonTopLevelArray="true"
            nxsd:encoding="UTF-8">
    <xsd:element name="Root-Element">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="topLevelArray" maxOccurs="unbounded" type="xsd:string"/>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>

When the JSON translator converts the XML to JSON format, the XML root elements are dropped. In the reverse direction, a root element is adding when converting JSON to XML; in such cases, the name of the root element is obtained from the schema. This occurred because JSON can have multiple top-level object properties that resulted in multiple root elements which, on the other hand, is not valid in XML.  An nxsd annotation nxsd:jsonTopLevelArray="true" can be set in the schema to indicate that the JSON will have a top-level array.

One of the options to generate the required XML Schema format is to use the Native Format Builder.  Read this blog about using Native Format Builder: http://www.ateam-oracle.com/introduction-to-fmw-12c-rest-adapter/, and Oracle documentation: http://docs.oracle.com/middleware/1213/soasuite/develop-soa/soa-rest-integration.htm#SOASE88861

Derek Kam

Consulting Solutions Architect

Derek Kam is a Consulting Solutions Architect in the A-Team at Oracle Corporation. He works closely with customers and partners, worldwide, providing guidance on architecture, best practices, troubleshooting and how best to use Oracle Cloud Services and products to solve customer business needs. Derek is a multi-skilled IT professional with more than 26 years of experience, possessing a wide range of experience and expertise in the Oracle Fusion Middleware and Oracle Clouds (PaaS and IaaS) technical and architecture design, development, software testing and quality assurance, and project management. Prior to joining Oracle in 2012, Derek has worked in consulting, financial and retail industries.


Previous Post

Avoiding LibOVD Connection Leaks When Using OPSS User and Role API

Guest Author | 3 min read

Next Post


Integrating Oracle Transaction Business Intelligence (OTBI) Soap API

Jay Pearson | 7 min read