XSLT transformations in Oracle Service Bus

This is just a quick tip on how to perform XSLT-transformations in OSB. Since transforming messages from one format to another is a crucial feature in any ESB you would think that setting it up would be obvious.. That’s what we thought
as well, but try as we might, we could not make it work. Once we figured it out we decided to write this blog in case someone else is facing the same issue.

A really short introduction to OSB
OSB is a rebranded version Aqualogic Service Bus which Oracle acquired when purchasing BEA. It is an “enterprise” level ESB built on top of the Weblogic application server with all the bells and whistles except maybe for good documentation. A key feature of the development environment is that message routes and actions are configured in a GUI and not in code or XML-configuration files. You can develop either using the OSB Workshop based on Eclipse or the OSB Console webapp. If you think this means a lot of pointing and clicking you are correct. In general, programmers tend to be wary of relying on code generation GUI wizards for development and for good reasons: What kind of code does it generate? Do I understand what it does and what do I do if something goes wrong? However, if you are going to enter the world of OSB you really must cast such worries aside and focus on the benefits it gives. Amongst other things, defining transformations by dragging lines between two sets of nodes, which OSB (or rather the Eclipse-based Workshop) makes possible through the XQuery editor, is quite awesome compared to writing it all in code. Likewise, having a clear overview of the various processes is a very good thing. If this does not make you change your mind, then you can hopefully agree to that a visual representation makes it easier for us as developers to explain stuff to Business People.

The task at hand
So what we wanted to do seemed really simple. We had an XML-message in one format and wanted to transform it to another format. This was part of an exercise we were developing for showing how the basic Enterprise Integration Patterns can be implemented in different technologies. Previously, we had done an implementation using Apache Camel using it’s really nifty DSL in which the transformation could be specified like this:

from("jms:queue:sourceQueue")
.to("xslt:com/jayway/eip/transformations/itransformation.xsl")
.to("jms:queue:targetQueue");

Listing 1: Pure elegance in three rows. The term ‘nifty’ springs to mind.

So how to do the same thing in OSB? Well the documentation had these help sections to offer when we searched for XSLT transformation information:

100. Testing XSLT Transformations
95. Resolving Unresolved XSL Transformation References
88. Binding External XSLT Resources to Inline XQueries
88. Editing XSL Transformations
79. Adding an XSL Transformation
37. Locating XSL Transformations

Listing 2: Ah! So transformations can be tested, resolved, bound, edited, added and located but how do you actually use them?

The documentation is very detailed but in our view it focuses on the wrong things. Yes, it might be good to give step by step instructions on how to add an XSLT resource but since this is done in the same way for all resources in OSB it would be better to focus on describing how to do something useful with it. When reading the documentation fails it is usually time to try our trusted friend Google but in this case it gave us nothing useful (were are all the OSB gurus hanging out?). Now, we are quite adept at googling (a crucial developer skill) and so this was quite worrying. We didn’t give up though and with some extra help from the nice people at Oracle we finally got what we needed to put it together.

The solution “How to apply an XSLT transformation in OSB”

And so here it is, step by step. Enjoy!

Step 0: Create a Session
Whenever you want to add, edit or delete something, you need to start a new session. When done with your changes, you end the session. By doing so, OSB can keep track of your changes and allow you to cancel your current changes or rollback earlier ones.

Step 1: Define a proxy service

Define a proxy service using the XSD of the source as the request message type and the XSD of the target as the response message type.

Image 1: The message type configuration

Step 2: Add a pipeline pair

Edit the proxy and select to add a pipeline pair from the context menu.

Image 2: A pipeline pair added to the message flow.

Step 3: Add a stage

While hovering over the Request Pipeline, Select ‘Add Stage’ from the context menu.

Image 3: A stage added to the message flow.

Step 4: Edit stage

From the context menu, select ‘Edit Stage’ to get to the Stage Editor.

Image 4: The context menu.

Step 5: Add a Replace action

Select to add a new Replace-action from the Message Processing sub-menu of the context menu.

Image 5: The sub-menu of the context menu.

Step 6: Select the source Xpath

Click on the Xpath-link to get to the Xpath editor.

Image 6: The Xpath link to click.

Step 7: Edit the source Xpath

Specify a valid Xpath , or use the GUI to browse available variable structures to find, the element to replace.

Image 7: The Xpath Expression Editor.

The Xpath Expression Editor is a very useful tool that allows the user to define a Xpath through navigating available elements or just write it into the editor manually.

Step 8: Specify the variable to replace

Enter the name of the variable to replace in the field. While doing so, make sure to tick the “Replace entire node” checkbox.

Image 8: The input field of the variable to replace.

Step 9: Select the replacement XPath

Click the ‘Expression’ link to edit the Xpath.

Image 9: Notice the 'Expresion' link that can be clicked to edit the Xpath of the replacement.

Step 10. Select to use a XSLT resource

Click on the XSLT Resources link to bring up the XSLT Resources view.

Image 10: The XQuery/XSLT Expression Editor

Step 11: Select to browse for the XSLT resource to use

Click the Browse button to browse for an XSLT to use.

Image 11: The XSLT Resources view

Step 12: Select the XSLT resource to use

From the list of available XSLT resources (that you have previously added to your project), select the XSLT to handle this transformation.

Image 12: The list of available XSLT resources.

Step 13: Bind the input for the XSLT transformation

Back in the Editor, specify $body as the input document to give to the XSLT to perform the transformation upon.

Image 13: The XQuery/XSLT Expression Editor, now set up for an XSLT resource.

Take a moment to test and validate your definition using the available tools in the editor. When done, press the ‘Save’ -button to close the view.

Step 14: Save and close the Stage Editor

Back in the Stage Editor, Click the ‘Save’-Button to save and close this view.

Image 14: The Stage Editor

Take a moment to test and validate your definition using the available tools in the editor. When done,  press the ‘Save’ -button to close the view.

Step 15: Save and close the Message Flow Editor

Press the ‘Save’-button to Save and close the Message Flow Editor.

Image 15: The complete message flow.

Step 16: Done!

Well, almost. Don’t forget to activate your session in order to commit the changes.

This Post Has 25 Comments

  1. Hello. We had Oracle in for a tech briefing and they seemed to push XQuery as the preferred transformation technology. Is there a performance cost in OSB by using XQuery versus XSL? We’re looking to migrate many of our existing BPEL projects that use XSL to the OSB platform and it would be nice to reuse the XSLs we’ve created.

  2. Hi,

    Not knowing the details of your problem I would have to respond with the ever popular “It depends”. It would likely depend on the structure of the documents you are transforming from and to, the size of the documents etc.

    What I would do in your situation is to implement one representative transformation in XQuery and then do performance tests comparing it to the same transformation using XSLT. My guess is that the difference will not be significant but it is always better to check.

    Even if it turns out that XQuery is faster in your case there is of course always the question if that performance gain is worth discarding the time invested and the knowledge you have in XSLT in order to reimplement the transformations. In my experience, that would be hard to sell to the business owner unless we are talking of really critical performance issues.

    Anyway, sorry about not having a straight answer to your question. Maybe someone else will chime in and set off the XSLT vs XQuery flame war :-)

  3. I don’t have any benchmarks to base any straight answers on either, so here are some thoughts and guesses:

    It would seem that if nothing else, XQuery has much more momentum than XSLT while most implementations of XSLT is still on version 1.0 (atleast in the Java community).

    The fact that XSLT was just recently added to OSB, and yet Oracle choose to go with a XSLT 1.0 implementation, is another sign of how XSLT seems to be left behind.

    Many XSLT 1.0 templates suffer from over-complex expression there to overcome shortcomings in the old spec, which PROBABLY makes these transformations slower than they have to be, and therefore PROBABLY slower than the same solution implemented in XQuery .

  4. Is there anyway I could use Xpath functions like numeric-subtract, op:numeric-multiply in Service Bus Xpath/XSLT expression editor, Appreciate your response

  5. Hi,
    how I can pass parameters at XSLT trasformation?

    Thk
    L.

  6. Hi Leo,

    When a XSLT-transformation has input parameters they will show up in the section called “3. Bind Variables” in the XSLT expression editor where you can bind them in the same way as when you bind the input.

    /olof

  7. I’m trying to make a transformation between t A Proxy BS, but
    BS interface is Oracle UCM -> GenericSoapPort.wsdl really is a
    interface very generic, almost impossible, the worst is that there is no example for
    make changes to this guy. I’m using Oracle JDeveloper 11g
    Studio Edition Version 11.1.1.3.0. SOA Composite Editor
    11.1.1.3.0.25.57. Map XSLT editor is very basic, ie all
    I’m programming.

    I have not had much time to explore XQuery, but for now it makes me
    complicated further with XSLT.

    Know any tool to help me 100% with XSLT transformations.

    This is my problem, GenericSoapPort.wsdl :

    GenericSoapPort.xsd :

  8. GenericSoapPort.wsdl

    GenericSoapPort.xsd :

  9. Magnus & Olof,

    Thank you for the extremely helpful blog posting. I laughed in the beginning because I followed the same “RTFM, then google” procedure. Thankfully, this post was the top of the result list!

  10. This is really help full and really appreciate your work.

  11. Hi,

    Is it possible to dynamically assign XSLT in Expression?

    Thanks!!!

    1. Hi,

      I am not sure that I understand exactly what you mean by assigning XSLT stylesheets dynamically but if you want to use different stylesheets depending on some property of the message you can easily achieve this using a “Conditional Branch” node in the message flow.

      See: this link for more information.

  12. Hi Olof,

    I mean in my Java class, I will be dynamically setting the XSLT value(e.g. “esb/xslt/transformXSLT”) in my request then I will access that value in ESB so that I can put it in Expression Editor as the XSLT value. All my readings are pointing me to do an XQuery instead. I’m not sure if there is a better way to do it.

    Thanks a lot!

  13. Hi guys i have a problem, when I test my sample, the response is equals that the request, I tried to modify my respone but always i have the request shcema as a response but when I created my proxy service i asigned response shema to response message and request schema to request schema. My response and request shemas are diferents. Could you help me?. Thanks in advance.

  14. Hi guys..thanks for this great post..can I have a copy of the .xsd and .xlst that you have used in above sample. Thanks :)

  15. Hi,
    I ma trying to pass two input parameters to my XSLT, wher the two input parameters are inturn an xml structure.both input parameters are xml that i receive from a previous service callout.I assigned these two parameters in the binding variables of the XSLT.
    I get this exception:
    com.sun.org.apache.xalan.internal.xsltc.TransletException: com.sun.org.apache.xml.internal.utils.WrappedRuntimeException: Validation failed for XSLT BA_AmadeusWebserviceProxy_V1/XSLT/org.apache.xmlbeans.impl.store.Xobj$ElementXobj@2aba7a3: Referenced component (XSLT BA_AmadeusWebserviceProxy_V1/XSLT/org.apache.xmlbeans.impl.store.Xobj$ElementXobj@2aba7a3) not found.
    Pls let me know how do i pass an XML in a parameter.It is expecting a Xobj.I am not sure how to pass it to the XSLT.
    My XSLT Looks like this:

  16. The XSLT didn’t get copied in my previous post.Pls help me if you know how i can pass a reference XML to an XSLT.

  17. Hello,This is the code of a xq transformation..Can anybody suggest me the alternative of group by clause here..as i dun want my elements to be selected in any particular order….Can anybody suggest how to use Let Clause here??

    {
    for $item1 in $executeReturn1/ns1:referencedtransactions/ns1:item

    group $item1 as $group by
    $item1/ns1:btOhinvamtDoc/ns1:amount as $key0,
    $item1/ns1:btOhstatus as $key1,
    $item1/ns1:btOhrefnum as $key2,
    $item1/ns1:btOhduedate/ns1:date as $key3,
    $item1/ns1:csId as $key4
    return

    }
    SUCCESS

    };

  18. Hello,This is the code of a xq transformation..Can anybody suggest me the alternative of group by clause here..as i dun want my elements to be selected in any particular order….Can anybody suggest how to use Let Clause here??

    {
    for $item1 in $executeReturn1/ns1:referencedtransactions/ns1:item

    group $item1 as $group by
    $item1/ns1:btOhinvamtDoc/ns1:amount as $key0,
    $item1/ns1:btOhstatus as $key1,
    $item1/ns1:btOhrefnum as $key2,
    $item1/ns1:btOhduedate/ns1:date as $key3,
    $item1/ns1:csId as $key4
    return

    }
    SUCCESS

    };

  19. after return dese statements are here…which is no6t getting pasted in above code..
    return

    }
    SUCCESS

  20. Great blog post!

    I (have to) start with OSB these days. It is unbelievable, that it is so heavyweight to do a little bit of integration logic!

    I smiled when you showed the Apache Camel example. I would prefer to use this lightweight, easy-to-use integration framework instead of OSB.

    Best regards,
    Kai Wähner (Twitter: @KaiWaehner)

  21. I forgot to mention that the OSB also has some advantages of course! For instance, as mentioned in the blog already, creating XPath expressions with the GUI designer is really nice.

    Therefore, you always have to compare pros and cons of lightweight vs. heavyweight ESBs…

    Best regards,
    Kai Wähner (Twitter: @KaiWaehner)

  22. Can only agree with Kai.
    We turned from OSB to Camel exactly because of it’s lightweight features. I think the example speaks for it self :-).
    Besides being lightweight, skill wise it’s more appealing to a java devs., and doesn’t require special OSB knowledge.
    For example when we need consultants to help out, we just have to look for java skills, and they are basically up and running within 1 day.

  23. Hi,

    Could you please provide an idea on how to edit/update the WSDL/XSD using OSB java API?

    Thanks,
    Anitha

  24. l tried to follow you tutorial but lm getting an error , Here is the full description of my project :

    l created a business service using an existing WSDL file ie Requisition WSDL , then l created a proxy service using existing Purchase Order swdl file and in the messaging option l then specified purchase Order xsd file as request and response .l then created a XSL Map file and in the CREATE SXL MAP l used Purchase Order schema as the Source and then l used Requisition Schema as Target .After creating a XSL file l did a auto Mapping from source to target schema . l then connected the pipeline to business service and this automatically created RouteNode with routing and inside routing the request Action and Response Action were created . With Pipeline opened l dragged the REPLACE component from pallete to Request Action .On the Replace properties l selected BODY as Location ,in the XPATH used this expression $body-request and the value l used XSLT resources and in the XSLT resources window l selected the xsl file l created and in the input document expression l entered $body-request .The problem here is that when l test my proxy services there is any error in the Pipeline route node saying Cannot find dispatch method for {http://PurchaseOrder.Purchasing.Service.Omnistall/}arg0 which is purchase order targetNameSpace
    lm using Jdeveloper 12C

Leave a Reply

Close Menu