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

Friday, January 19, 2018

Replace Namespace with XSLT in OSB

Recently, I'm working on a project and the vendor changed their framework for implementing their web services. This change caused their web service cannot fully compatible with existing WSDLs and the second level element will not have a correct namespace as before.

Before the change, the request will like below.
<ns0:getRelatedContacts xmlns:ns0="http://ws.crm.victor.com" xmlns:ns1="http://lib.ws.victor.com">
    <ns0:contactRequest>
        <ns1:FAID>FAID_1</ns1:FAID>
        <ns1:subscriptionId>subscriptionId_1</ns1:subscriptionId>
    </ns0:contactRequest>
</ns0:getRelatedContacts>

After the vendor change, the request will like below. The elment contactRequest lost its namespace.
<ns0:getRelatedContacts xmlns:ns0="http://ws.crm.victor.com" xmlns:ns1="http://lib.ws.victor.com">
    <contactRequest>
        <ns1:FAID>FAID_1</ns1:FAID>
        <ns1:subscriptionId>subscriptionId_1</ns1:subscriptionId>
    </contactRequest>
</ns0:getRelatedContacts>

The response has the same issue and second level element will not have a namespace. Due to the vendor cried they might take too much effort to fix it (I don't think it is true. :)), our team has to provide a solution to fix and make the service behavior we exposed to clients same as before and hence we need to find out a way to fix the namespace issue.

Definitely, there isn't a out-box solution. We have to create some code by ourselves to resolve this specific issue.

For replacing namespace, it is pretty simple with XSLT and can be done by a element copy. The next issue is to find out the second level element in the request to remove the namespace and adding the namespace back in response.

Here are the code for removing namespace from request.
<xsl:stylesheet version="1.0"  xmlns:xsd="http://www.w3.org/2001/XMLSchema"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
   
   <xsl:template match="/">
    <xsl:apply-templates/>
  </xsl:template>
  
  <xsl:template match="*[count(ancestor::node())=2]">
    <xsl:element name="{local-name()}">
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates select='@*|node()'/>
    </xsl:element>
  </xsl:template>

  <xsl:template match='@*|node()'>
    <xsl:copy>
        <xsl:apply-templates select='@*|node()'/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

Here are the code for adding namespace back in response.
<xsl:stylesheet version="1.0"  xmlns:xsd="http://www.w3.org/2001/XMLSchema"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
      
   <xsl:template match="/">
    <xsl:apply-templates/>
  </xsl:template>
  
  <xsl:template match="*[count(ancestor::node())=2]">
    <xsl:element name="{local-name()}" namespace="{namespace-uri(parent::node())}">
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates select='@*|node()'/>
    </xsl:element>
  </xsl:template>

  <xsl:template match='@*|node()'>
    <xsl:copy>
        <xsl:apply-templates select='@*|node()'/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

The above codes were tested in OSB 11g and 12c. They worked as what I expected.

Tuesday, May 14, 2013

OSB-SOAP Action Header Issue

Issue:
Recently, I worked on an existing code developed by somebody else long time ago and a defect was opened for SOAP action header issue. The invoked web service always complained 'no SOAPAction header!'.

As the business service was developed by vendor and they used RPC style, we have to define the business service as any XML service. (If we defined as a WSDL webservice, OSB threw exception when it got the response - unrecognized response.) As the business service was set an any XML service, it looks like the the OSB can automatically set soap action header.

Resolution:
In OSB proxy service, before the service callout, put a replace action to replace the soap action hdead in outbound.
In this application, I just used the soap action header of inbound to replace the one of outbound by the easiest way. (From the OSB console, I saw the soap action header is empty string for the initial request and same as the one needed for the service call, then I just copied them from Inbound Request.)

Note: A Transport Headers action looks like not work properly and the soap xml was modified by OSB automatically and caused an additional soap body was added to the soap envelop incorrectly.

SOAPAction References:

Thursday, March 01, 2012

XML Schema - Structure Style

XML Schema  Design Pattern: Russian Doll, Salami Slice, Venetian Blind, and Garden of Eden

Russian Doll
The Russian Doll design approach has a schema structure mirroring the instance document structure, e.g., declare a Book element and within it declare a Title element followed by a Publisher element:

<xsd:element name="Book">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Title" type="xsd:string"/>
<xsd:element name="Publisher" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</element>

The instance document has all its components bundled together. Likewise, the schema is designed to bundle together all its element declarations.


Salami Slice
Salami Slice design disassembles the instance document into its individual components. In the schema, we define each component (as an element declaration), and then assemble them together:


<xsd:element name="Title" type="xsd:string"/>
<xsd:element name="Publisher" type="xsd:string"/>
<xsd:element name="Book">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="Title"/>
<xsd:element ref="Publisher"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>


Note how the schema declared each component individually (Title, and Publisher) and then assembled them together in the creation of the Book component


Venetian Blind

Similar to the Russian Doll approach in that they both use a single global element.  The Venetian Blind approach describes a modular approach by naming and defining all type definitions globally (as opposed to the Salami Slice approach which declares elements globally and types locally).  Each globally defined type describes an individual "slat" and can be reused by other components.  In addition, all the locally declared elements can be namespace qualified or namespace unqualified (the slats can be "opened" or "closed") depending on the elementFormDefault attribute setting at the top of the schema.  If the namespace is unqualified then the local elements in the instance document must not be qualified with the prefix of the namespace.


<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="TargetNamespace" xmlns:TN="TargetNamespace" xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified" attributeFormDefault="unqualified">
   <xs:element name="Book" type="TN:BookType" maxOccurs="unbounded"/>
   <xs:complexType name="BookType">
       <xs:sequence>
           <xs:element name="Title" type="xsd:string"/>
           <xs:element name="Publisher"type="xsd:string"/>
           <xs:element name="PeopleInvolved" type="TN:PeopleInvolvedType" maxOccurs="unbounded"/>
       </xs:sequence>
   </xs:complexType>
   <xs:complexType name="PeopleInvolvedType">
       <xs:sequence>
           <xs:element name="Author"type="xsd:string"/>
       </xs:sequence>
   </xs:complexType>
</xs:schema>




Garden of Eden
The Garden of Eden design is a combination of Venetian Blind and Salami Slice. You define all the elements and types in the global namespace and refer to the elements as required.

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="TargetNamespace" xmlns:TN="TargetNamespace"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified" attributeFormDefault="unqualified">
   <xs:complexType name="BookType">
       <xs:sequence>
           <xs:element ref="Title"/>
           <xs:element ref="Publisher"/>
           <xs:element ref="PeopleInvolved" maxOccurs="unbounded"/>
       </xs:sequence>
   </xs:complexType>
   <xs:complexType name="PeopleInvolvedType">
       <xs:sequence>
           <xs:element ref="Author"/>
       </xs:sequence>
   </xs:complexType>
   <xsd:element name="PeopleInvolved type="TN:PeopleInvolvedType"/>
   <xs:element name="Title" type="xsd:string"/>
   <xs:element name="Publisher"type="xsd:string"/>
   <xs:element name="Author"type="xsd:string"/>
   <xs:element name="Book" type="TN:BookType" maxOccurs="unbounded"/>
</xs:schema>

Because it exposes all its elements and types globally, Garden of Eden, like Salami Slice, is completely reusable. However, because Garden of Eden exposes multiple elements as global ones, there are many potential root elements.



Monday, January 25, 2010

Xerces

Xerces is a collection of software libraries for parsing, validating, serializing and manipulating XML. The library implements a number of standard APIs for XML parsing, including DOM, SAX and SAX2.

XML Data Binding

XML data binding refers to the process of representing the information in an XML document as an object in computer memory. This allows applications to access the data in the XML from the object rather than using the DOM or SAX to retrieve the data from a direct representation of the XML itself.

Java Architecture for XML Binding (JAXB)
JABX allows Java developers to map Java classes to XML representations. JAXB provides two main features: the ability to marshal Java objects into XML and the inverse, i.e. to unmarshal XML back into Java objects. In other words, JAXB allows storing and retrieving data in memory in any XML format, without the need to implement a specific set of XML loading and saving routines for the program's class structure.

Usage of JAXB
The tool "xjc" can be used to convert XML Schema and other schema file types (as of Java 1.6, RELAX NG, XML DTD, and WSDL are supported experimentally) to class representations. Classes are marked up using annotations from javax.xml.bind.annotation.* namespace, for example, @XmlRootElement and @XmlElement. XML list sequences are represented by attributes of type java.util.List. Marshallers and Unmarshallers are created through an instance of JAXBContext.
In addition, JAXB includes a "schemagen" tool which can essentially perform the inverse of "xjc", creating an XML Schema from a set of annotated classes.

XMLBeans
It is a tool that allows access to the full power of XML in a Java friendly way. The idea is to take advantage of the richness and features of XML and XML Schema and have these features mapped as naturally as possible to the equivalent Java language and typing constructs. XMLBeans uses XML Schema to compile Java interfaces and classes that can then be used to access and modify XML instance data. Using XMLBeans is similar to using any other Java interface/class: with methods like getFoo or setFoo, just as when working with Java. While a major use of XMLBeans is to access XML instance data with strongly typed Java classes there are also APIs that allow access to the full XML infoset (XMLBeans keeps XML Infoset fidelity) as well as to allow reflection into the XML schema itself through an XML Schema Object model.

Usage of XMLBean
To accomplish the above objectives, XMLBeans provides three major APIs:
  • XmlObject
  • XmlCursor
  • SchemaType
    XmlObject: The java classes that are generated from an XML Schema are all derived from XmlObject. These provide strongly typed getters and setters for each of the elements within the defined XML. Complex types are in turn XmlObjects. For example getCustomer might return a CustomerType (which is an XmlObject). Simple types turn into simple getters and setters with the correct java type. For example getName might return a String.
    XmlCursor: From any XmlObject the developer can get an XmlCursor. This provides efficient, low level access to the XML Infoset. A cursor represents a position in the XML instance. The cursor can be moved around the XML instance at any level of granularity needed from individual characters to Tokens.
    SchemaType: XMLBeans provides a full XML Schema object model that can be used to reflect on the underlying schema meta information. For example, the developer might generate a sample XML instance for an XML schema or perhaps find the enumerations for an element so that they may be displayed.
  • XML Parser

    Java API for XML Processing - JAXP
    is one of the Java XML programming APIs. It provides the capability of validating and parsing XML documents. The three basic parsing interfaces are:
  • the Document Object Model parsing interface or DOM interface
  • the Simple API for XML parsing interface or SAX interface
  • the Streaming API for XML or StAX interface (added in JDK 6; separate jar available for JDK 5)

    XML Parsing
    Traditionally, XML APIs are either:
  • tree based - the entire document is read into memory as a tree structure for random access by the calling application
  • event based - the application registers to receive events as entities are encountered within the source document.
    Both have advantages; the former (for example, DOM) allows for random access to the document, the latter (e.g. SAX) requires a small memory footprint and is typically much faster.

    These two access metaphors can be thought of as polar opposites. A tree based API allows unlimited, random, access and manipulation, while an event based API is a 'one shot' pass through the source document.

    Event-based XML Parsing Libs
    SAX is the Simple API for XML, originally a Java-only API. SAX was the first widely adopted API for XML in Java, and is a "de facto" standard.

    A parser which implements SAX (ie, a SAX Parser) functions as a stream parser, with an event-driven API. The user defines a number of callback methods that will be called when events occur during parsing. The SAX events include:
  • XML Text nodes
  • XML Element nodes
  • XML Processing Instructions
  • XML Comments

    Events are fired when each of these XML features are encountered, and again when the end of them is encountered. XML attributes are provided as part of the data passed to element events. SAX parsing is unidirectional; previously parsed data cannot be re-read without starting the parsing operation again.

    DOM-based XML Parsing Libs
    JDOM
    An open source Java-based document object model for XML that was designed specifically for the Java platform so that it can take advantage of its language features. JDOM integrates with Document Object Model (DOM) and Simple API for XML (SAX), supports XPath and XSLT. It uses external parsers to build documents.

    DOM4J
    An open source Java library for working with XML, XPath and XSLT. It is compatible with DOM, SAX and JAXP standards.

    Streaming API for XML (StAX)
    An application programming interface (API) to read and write XML documents, originating from the Java programming language community.

    StAX was designed as a median between these two opposites. In the StAX metaphor, the programmatic entry point is a cursor that represents a point within the document. The application moves the cursor forward - 'pulling' the information from the parser as it needs. This is different from an event based API - such as SAX - which 'pushes' data to the application - requiring the application to maintain state between events as necessary to keep track of location within the document.

    StAX XML Parsing Libs
    Apache Axiom
    A a light weight XML object model based on top of Stax and also provides lazy object building.
  •