Friday, May 2, 2014

Transforming the REST XML message to SOAP message - OSB

Transforming the REST XML message to SOAP message - OSB

This post will explain how to Transform the REST XML message to SOAP message in OSB

While receiving the response from REST interface  with the content type as application\xml, the input XML will be plain without the target namespace specified.
But if you are invoking the BPEL with this message the BPEL cant perform any xpath operations on this message without target namespace.The target namespace should be added to the message.

The XSLT can be used to add the name space to the XML message but before performing this operation the SOAP envelope of the body variable should be removed
After removing the namespace the XML should be assigned to the body variable to send to target system.

Follow the below steps to achieve the same:

Remove SOAP Envelope:

The below XSLT will help as to remove the namespace from the XML.

Create a XSLT resource from SB console.
Add a Assign activity with the XSLT resource
Assign the output to a temp variable - var1.

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="@* | node()">
        <xsl:copy>
          <xsl:apply-templates select="@* | node()" />
        </xsl:copy>
      </xsl:template>

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




Transforming the SOAP message to REST XML message- OSB

Transforming the SOAP message to REST XML message- OSB

While invoking the REST interface from OSB with the content type defined as application\xml, the target system will expect the simple XML message without the target namespace specified.

The XSLT can be used to remove the name space from SOAP message but before performing this operation the SOAP envelope of the body variable should be removed
After removing the namespace the XML should be assigned to the body variable to send to target system.

Follow the below steps to achieve the same:

Remove SOAP Envelope:

The below XSLT will help as to remove the namespace from the XML.

Create a XSLT resource from SB console.
Add a Assign activity with the XSLT resource
Assign the output to a temp variable - var1.

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="@* | node()">
        <xsl:copy>
          <xsl:apply-templates select="@* | node()" />
        </xsl:copy>
      </xsl:template>

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

Removing Namespace:

The below XSLT will help as to add the target namespace to the XML.

Create a XSLT resource from SB console.
Add a Assign activity with the XSLT resouce  to remove the namespace from the variable var1
Assign the ouput to a temp variable - var2

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="*">
        <xsl:element name="{local-name()}">
            <xsl:apply-templates select="@* | node()" />
        </xsl:element>
    </xsl:template>
    <xsl:template match="@*">
        <xsl:attribute name="{local-name()}">
            <xsl:value-of select="." />
        </xsl:attribute>
    </xsl:template>
    <xsl:template match="text() | comment() | processing-instruction()">
        <xsl:copy />
    </xsl:template>
</xsl:stylesheet>

Assign the content of var2 to body:

Add replace activity to replace the node contents of body with var2




Friday, July 20, 2012

Splitting an array of repeated elements into sub groups based on index in XSL

Splitting an array of repeated elements into sub groups based on index in XSL

Sometimes we may require splitting the array of repeated elements into sub groups based on index in XSL; this blog will explain the approach to do the same.

The below XSLT will select the first two order line items from the list of line items.
The same can be used to select the elements by passing startIndex and endIndex values.

<xsl:stylesheet version="1.0"
                xmlns:xsdLocal="http://www.reuters.com/ns/2007/01/25/GCAP/EAI/OrderManagement"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="startIndex">1</xsl:variable>
<xsl:variable name="endIndex">2</xsl:variable>
  <xsl:template match="/">
    <xsdLocal:orderRequest>
      <xsl:for-each select="/xsdLocal:UserIdRequest/xsdLocal:orderLineItem[(position() >= $startIndex) and (position() &lt;= $endIndex)]">
        <xsdLocal:orderLineItem>
          <xsdLocal:CRMOLIId>
            <xsl:value-of select="xsdLocal:CRMOLIId"/>
          </xsdLocal:CRMOLIId>
          <xsdLocal:parentOrderItemId>
            <xsl:value-of select="xsdLocal:parentOrderItemId"/>
          </xsdLocal:parentOrderItemId>
          <xsdLocal:rootItemId>
            <xsl:value-of select="xsdLocal:rootItemId"/>
          </xsdLocal:rootItemId>
      </xsdLocal:orderLineItem>
      </xsl:for-each>
    </xsdLocal:orderRequest>
  </xsl:template>
</xsl:stylesheet>

Input XML:

<?xml version="1.0" encoding="UTF-8" ?>
<UserIdRequest  xmlns="http://www.reuters.com/ns/2007/01/25/GCAP/EAI/OrderManagement">
  
   <orderLineItem>
      <CRMOLIId>CRMOLIId529</CRMOLIId>
      <parentOrderItemId>parentOrderItemId530</parentOrderItemId>
      <rootItemId>rootItemId531</rootItemId>
    
   </orderLineItem>
   <orderLineItem>
        <CRMOLIId>CRMOLIId529</CRMOLIId>
      <parentOrderItemId>parentOrderItemId530</parentOrderItemId>
      <rootItemId>rootItemId531</rootItemId>
   </orderLineItem>
   <orderLineItem>
       <CRMOLIId>CRMOLIId529</CRMOLIId>
      <parentOrderItemId>parentOrderItemId530</parentOrderItemId>
      <rootItemId>rootItemId531</rootItemId>
   </orderLineItem>
  
    <orderLineItem>
       <CRMOLIId>CRMOLIId529</CRMOLIId>
      <parentOrderItemId>parentOrderItemId530</parentOrderItemId>
      <rootItemId>rootItemId531</rootItemId>
   </orderLineItem>
  
    <orderLineItem>
       <CRMOLIId>CRMOLIId529</CRMOLIId>
      <parentOrderItemId>parentOrderItemId530</parentOrderItemId>
      <rootItemId>rootItemId531</rootItemId>
   </orderLineItem>
  
    <orderLineItem>
       <CRMOLIId>CRMOLIId529</CRMOLIId>
      <parentOrderItemId>parentOrderItemId530</parentOrderItemId>
      <rootItemId>rootItemId531</rootItemId>
   </orderLineItem>
</UserIdRequest>

Output XML:

<?xml version = '1.0' encoding = 'UTF-8'?>
<xsdLocal:orderRequest xmlns:xsdLocal="http://www.reuters.com/ns/2007/01/25/GCAP/EAI/OrderManagement" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.reuters.com/ns/2007/01/25/GCAP/EAI/OrderManagement file:/D:/Albin/DevCodeBase/2012_R5/CRM_EAI_code_deploy/code/CRM61OM/CPFGOM_OrderSplitter/EAI.MSG.OM.125_OrderRequest.xsd">
   <xsdLocal:orderLineItem>
      <xsdLocal:CRMOLIId>CRMOLIId529</xsdLocal:CRMOLIId>
      <xsdLocal:parentOrderItemId>parentOrderItemId530</xsdLocal:parentOrderItemId>
      <xsdLocal:rootItemId>rootItemId531</xsdLocal:rootItemId>
   </xsdLocal:orderLineItem>
   <xsdLocal:orderLineItem>
      <xsdLocal:CRMOLIId>CRMOLIId529</xsdLocal:CRMOLIId>
      <xsdLocal:parentOrderItemId>parentOrderItemId530</xsdLocal:parentOrderItemId>
      <xsdLocal:rootItemId>rootItemId531</xsdLocal:rootItemId>
   </xsdLocal:orderLineItem>
</xsdLocal:orderRequest>


Finding the distinct values of an element in a XSL


Finding the distinct values of an element in a XSL

Sometimes we may have the requirement to identify the distinct elements in the input XML. Key function will help us to identify the distinct elements in the XSL.

The key () function returns a node-set from the document, using the index specified by an <xsl:key> element.

Syntax:

node-set key(string, object)
string - Specifies the name of an xsl:key element
object - A string to search for

The below XSL will find the distinct nextaction1 available in the XML.

TransDistinctNextAction1.xsl

<xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsdLocal="http://www.reuters.com/ns/2007/01/25/GCAP/EAI/OrderManagement">
  <xsl:key name="orderlines-by-n1" match="/xsdLocal:extendedOrderRequest/xsdLocal:orderLineItem" use="xsdLocal:nextAction1"/>
 
  <xsl:template match="/">
    <xsdLocal:distinctNextActions>
      <xsdLocal:nextAction>
        <xsdLocal:nextAction1>
          <xsl:for-each select="/xsdLocal:extendedOrderRequest/xsdLocal:orderLineItem[generate-id(.) = generate-id( key('orderlines-by-n1', xsdLocal:nextAction1)[1])]">
            <xsdLocal:value>
              <xsl:value-of select="xsdLocal:nextAction1"/>
            </xsdLocal:value>
          </xsl:for-each>
        </xsdLocal:nextAction1>       
      </xsdLocal:nextAction>
    </xsdLocal:distinctNextActions>
  </xsl:template>
</xsl:stylesheet>


  <xsl:key name="orderlines-by-n1" match="/xsdLocal:extendedOrderRequest/xsdLocal:orderLineItem" use="xsdLocal:nextAction1"/>

                      Find the orderLineItems based on the nextaction1

          <xsl:for-each select="/xsdLocal:extendedOrderRequest/xsdLocal:orderLineItem[generate-id(.) = generate-id( key('orderlines-by-n1', xsdLocal:nextAction1)[1])]">

                        Find the unique nextaction1 values from the orderLineItems

Input XML:

<?xml version="1.0" encoding="UTF-8" ?>
<extendedOrderRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.reuters.com/ns/2007/01/25/GCAP/EAI/OrderManagement">
  
    <orderLineItem>
      <CRMOLIId>CRMOLIId36</CRMOLIId>
      <rootItemId>rootItemId37</rootItemId>
      <parentOrderItemId>parentOrderItemId38</parentOrderItemId>
      <actionCode>actionCode39</actionCode>     
      <nextAction1>nextAction175</nextAction1>     
   </orderLineItem>
   <orderLineItem>
      <CRMOLIId>CRMOLIId36</CRMOLIId>
      <rootItemId>rootItemId37</rootItemId>
      <parentOrderItemId>parentOrderItemId38</parentOrderItemId>
      <actionCode>actionCode39</actionCode>     
      <nextAction1>nextAction175</nextAction1>
   </orderLineItem>
   <orderLineItem>
      <CRMOLIId>CRMOLIId36</CRMOLIId>
      <rootItemId>rootItemId37</rootItemId>
      <parentOrderItemId>parentOrderItemId38</parentOrderItemId>
      <actionCode>actionCode39</actionCode>     
      <nextAction1>nextAction17</nextAction1>
   </orderLineItem>
</extendedOrderRequest>

Output XML:

<?xml version = '1.0' encoding = 'UTF-8'?>
<xsdLocal:distinctNextActions xmlns:xsdLocal="http://www.reuters.com/ns/2007/01/25/GCAP/EAI/OrderManagement" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <xsdLocal:nextAction>
      <xsdLocal:nextAction1>
         <xsdLocal:value>nextAction175</xsdLocal:value>
         <xsdLocal:value>nextAction17</xsdLocal:value>
      </xsdLocal:nextAction1>
   </xsdLocal:nextAction>
</xsdLocal:distinctNextActions>



Wednesday, November 30, 2011

Removing empty nodes from XML using xslt


Removing empty nodes from XML using xslt

The below XSLT can be used to remove the empty nodes from the XML file.

<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output omit-xml-declaration="yes" indent="yes" />
<xsl:template match="node()|SDLT">
<xsl:if test="count(descendant::text()[string-length(normalize-space(.))>0] | @*[string-length(.)>0])">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:if>
</xsl:template>
<xsl:template match="@*">
<xsl:copy />
</xsl:template>
<xsl:template match="text()">
<xsl:value-of select="normalize-space(.)" />
</xsl:template>
</xsl:stylesheet>