Skip to main content

Advanced XSL transformation mediation of arrays in WebSphere ESB

Nay Lin (naylin@us.ibm.com), Senior Software Engineer, IBM Software Services for WebSphere, IBM
Nay Lin photo
Nay Lin is a senior software engineer at the IBM Software Services for WebSphere Business Integration Proof-of-Concept Lab in Burlingame, California. He is an IBM certified IT specialist with extensive experience using WebSphere Business Integration products and developing J2EE and SOA applications using Rational Software Architect and WebSphere Integration Developer. You can contact Nay at naylin@us.ibm.com.

Summary:  WebSphere Enterprise Service Bus V6 (WebSphere ESB) provides common connectivity between service consumers and providers in a Service Oriented Architecture (SOA). WebSphere ESB mediation flow components perform mediations between consumer and provider services to virtualize service location, identity, interaction pattern, protocol, and interfaces. Mediation flows can be composed of mediation primitives that operate on Service Message Objects. In working with mediation primitives, you often need to deal with XPath and XSL to specify routing conditions or to transform data between source and target destinations. Based on Eclipse 3.0, WebSphere Integration Developer V6 provides tools and wizards to develop these mediation flows and primitives, and this article shows you how to use it to apply advanced XSL transformations on business objects containing arrays.

Date:  18 Oct 2006
Level:  Intermediate
Activity:  461 views

Introduction

In WebSphere® mediation flows, the XSL transformation primitive is often used to map a source (consumer) service interface to a target (provider) service interface. The XSL Mapping Editor in WebSphere Integration Developer provides a graphical mapping environment to help you build the XSL file required for the transformation. This article show you how to create advanced XSL transformations involving arrays. The article assumes that you have WebSphere Integration Developer V6.0.1 or later with a WebSphere ESB embedded test server installed on your machine.

Start WebSphere Integration Developer

  1. From the Windows Start menu, select Programs => IBM WebSphere => Integration Developer V6.0.1 => WebSphere Integration Developer V6.0.1.
  2. In the workspace launcher dialog, enter the workspace location, such as C:\WIDws\WESBxsl.
  3. Click OK. By default WebSphere Integration Developer will open the Business Integration perspective.

Otherwise, open the Business Integration perspective:

  1. Click on the + symbol next to the Open perspective icon at the upper right corner of WebSphere Integration Developer window.
  2. From a list of perspectives, select Business Integration.

Create sample business objects and interfaces

First, create the interface and business objects used by the interface to be used as source and target interfaces for XSL transformation mediations. Typically, source and target interfaces will be different, requiring mediations. Since we are demonstrating how to manipulate business objects containing arrays (copying one or all elements, selective elements, and so on), we will use the same interface as source and target interface. The same methods can be applied when the source and the target interfaces are different.

First, create a new mediation module named XSLSamples:

  1. From the main menu, select File => New => Other.
  2. Select New => Mediation Module wizard and click Next.
  3. In New Mediation Module dialog, Enter Module Name as XSLSamples.
  4. Click Finish.

Create business objects

To create two business objects named customer in the above module:

  1. Select the module XSLSamples, right-click, and select New => Other => Business object.
  2. Enter customer as the name and click Finish. This will open the Business Object Editor.
  3. In the Business Object Editor, add three attributes of type String named as: id, name, and role.
  4. From the Properties page, check the required check box for the elements id and role.
  5. Save and close the editor.

To create a business object named customers as an array of customer business objects created above:

  1. Select the module XSLSamples, right-click, and select New => Other => Business object.
  2. Enter customer as the name and click Finish. This will open the Business Object Editor.
  3. Add an attribute named customer of the type customer defined above.
  4. In the Properties pane, check the array check box to make the attribute an array.
  5. Save and close the Business Object Editor.

The resulting business object should look like this in the Business Object Editor:

Figure 1. Customer business object
Business objects

Create a sample interface

To create the sample interface to be used as source and target interfaces:

  1. Select the module XSLSamples, right-click, and select New => Interface.
  2. In New Interface Wizard, enter MyService as Name.
  3. Click Finish. This will open the interface file editor.
  4. In the editor, right-click and select Add Request Response operation.
  5. Change the name of the operation from operation1 to send.
  6. Select the Update operation, right-click, and select Add input.
  7. Change the name of the input from input1 to inCustomers.
  8. Change the type of the input from string to customers. (Click on the old type String to browse to the customer business object type and select it.)
  9. Similarly, add an output named outCustomers of type customers.
  10. Save and close the interface.

Figure 2. MyService interface.
myService interface

Build the mediation and service components

Next, build the mediation component and the target service component.

Create a mediation component

To create a new mediation flow component:

  1. Open the Module Assembly Editor for the XSLSamples module. You will see a mediation component Mediation1 already created.
  2. Change the name of the component to XSLMediationComponent.
  3. Select the component, right-click, and select Add => Interface.
  4. In the Add Interface dialog, select MyService interface and click OK.
  5. Select the component, right-click, and select Add => Reference.
  6. In the Add reference dialog, keep MyServicePartner as the Reference name, select MyService interface, and click OK.

Create a target service component

To create a target service component:

  1. Drag the MyService interface from the Business Integration view and drop it onto the Module Assembly Editor.
  2. Select Component with no implementation type and click OK.
  3. Rename the component MyServiceComponent and save it.
  4. Select MyServiceComponent, right-click, and select Generate Implementation => Java™.
  5. In the Generate Implementation dialog, click OK. MyServiceComponentImpl.java will open in the Java Editor.
  6. Enter the following code snippet for the method send:
    public DataObject send(DataObject inCustomers) {
    	//TODO Needs to be implemented
    	System.out.println("MyServiceComponent invoked");
    	return inCustomers;
    }
    

  7. Save and close the editor.
  8. In the module assembly diagram, right-click XSLMediationComponent and select Wire to Existing.

    The module editor will find the target component with a matching interface (MyServiceComponent) and wire the reference to the target service. The resulting assembly diagram should look like this:

    Figure 3. Module assembly diagram
    Assembly Diagram

  9. Save the assembly diagram.

Build mediation rlows for implementations

In the following sections, you will build two mediation flows that will be used as alternate implementations of the mediation component. The first mediation flow demonstrates two types of copying data: copying the whole input array to the output array, and selectively copying customers in a role of Manager and sending them to a target service (implemented in Java) that returns the copied customers as a response. The second mediation flow demonstrates the use of XSLT functions. WebSphere Integration Developer allows only a single mediation component in a mediation module, so you need to switch between the two mediation flows as implementation of the same mediation component.

Create the first mediation flow

  1. Select the XSLMediationComponent from the assembly diagram, right-click, and select Generate Implementation.
  2. Click OK in the Generate Implementation dialog. The Mediation Flow Editor will open.
  3. In the top operation connections window, connect the send operation from the MyService interface to the send operation from MyServicePartner. The Mediation Flow Editor will open:

Figure 4. Mediation flow editor.

Mediation Flow Editor
  1. Drag and drop the XSL transformation primitive from the palette on to the Mediation Flow Editor pane.
  2. Connect the out terminal of MyService_send_input to the in terminal of the XSL transformation primitive.
  3. Connect the out terminal of the XSL transformation primitive to the in terminal of the MyServicePartner_send_Callout. The resulting diagram in the editor should look like this:

Figure 5. Mediation Request Flow
Mediation flow xsl transform 1

Implement XSL mapping for copying arrays

  1. Select the XSL Transformation and open the Properties editor window at the bottom pane.
  2. Select the Details tab.
  3. Click New to create a new XSL mapping.
  4. In the new XSL mapping dialog, click Finish. The visual XSL Mapping Editor will open.
  5. Expand the source and target trees all the way to the bottom branch.
  6. Drag customer[0*] from the source to customer[0*] of the target.
  7. Drag each member element of customer: id, name, and role from the source to those of the target.
  8. Save the XSL Mapping Editor.

Figure 6. XSL Mapping editor
XSL mapping

If you do not map customer[0*] but mapped just individual elements under it, then only the first element of the customers array will be copied. If you drag only customers element from the source to customers element of the target without mapping individual elements under it, then only required elements (as defined in the schema) will be copied.

Now to generate XSL from the above graphical mapping:

  1. In the Mediation Flow Editor, select XSL Transformation 1.
  2. From the Details pane of the Properties view, click Regenerate XSL to generate the XSL file corresponding to the mapping that you just defined above.
  3. Click OK on the dialog box saying that XSL generation is complete.
  4. Click Edit next to the XSL file name to view the generated XSL file, part of which should look like this:
    <!-- Newly-defined element template -->
    <xsl:template name="body">
    	<body>
    		<xsl:call-template name="send"/>
    	</body>
    </xsl:template>
    
    <!-- Newly-defined element template -->
    <xsl:template name="send">
    	<send>
    		<xsl:call-template name="inCustomers"/>
    	</send>
    </xsl:template>
    
    <!-- Newly-defined element template -->
    <xsl:template name="inCustomers">
    	<inCustomers>
    		<xsl:apply-templates select="/body/send/inCustomers/customer"/>
    	</inCustomers>
    </xsl:template>
    

  5. After reviewing the generated XSL file, close the XSL Editor.

Now implement the response flow:

  1. Select the Response: send tab of the Mediation Flow Editor to open the response flow diagram. You are not performing any mediation on the response flow; instead you will just pass the response through. Therefore connect the out terminal of MyServicePartner_send_CalloutResponse to the in terminal of MyService_send_InputResponse.
  2. Save and close the Mediation Flow Editor.

Test the XSLMediationComponent

To test the completed mediation component:

  1. Start the WebSphere ESB V6 server from the Servers view.
  2. Select the server, right-click, and select Add and Remove Projects.
  3. In the Add and Remove Projects dialog, select XSLSamplesApp, add it to the server, and click Finish.
  4. Open the Module Assembly Editor.
  5. Select XSLMediationComponent from the assembly diagram, right-click, and select Test Component.
  6. In the Component test window, select the Configuration tab and remove MyServiceComponent from the list of emulators. Switch back to the Events tab.
  7. Enter the following data in the Initial request parameters and click Continue:

    Figure 7. Component Test Input
    Component test input 1

    You may select inCustomers under the Name column, right-click, and select Add value to pool to save the data for later use.

  8. In the Select Deployment Location dialog, select WebSphere ESB Server V6 and click Finish.
  9. The output data should be the same as the input data since all elements of the array are copied.

Figure 8. Component test output
Component test output 1

Implement XSL for content-based copy of array elements

XSL lets you specify the predicate (index) of elements of an array dynamically by using the value of the other XML elements. Specifying an array index is equivalent to evaluating a predicate to Boolean statements in XPath terminology. When the condition is true, the specified element is selected. In general, the expression can be any location path in your input/source xml or literal values. There is a restriction imposed by the JXPath engine used by WebSphere Integration Developer on the XPath expressions used for evaluating the predicates: a path should exclusively use the child:: and attribute:: axes and have no context-dependent predicates. For the XSL transformation primitive to copy only customer elements with role is manager, you can edit the generated XSL file directly, since the current XSL Visual Mapping Editor does not let you do this. Make sure you do not regenerate the XSL file after modifying it.

  1. Open the XSL source: in the Details view of the Mediation Flow Editor, click Edit next to the XSL file.
  2. In the XSL file, replace /body/route/customers/customer with /body/route/customers/customer[role='manager']. Part of the resulting XSL file should look like this:
    <!-- Newly-defined element template -->
    <xsl:template name="body">
    	<body>
    		<xsl:call-template name="send"/>
    	</body>
    </xsl:template>
    
    <!-- Newly-defined element template -->
    <xsl:template name="send">
    	<send>
    		<xsl:call-template name="inCustomers"/>
    	</send>
    </xsl:template>
    
    <!-- Newly-defined element template -->
    <xsl:template name="inCustomers">
    	<inCustomers>
    		<xsl:apply-templates select="/body/send/inCustomers/customer[role='manager']"/>
    	</inCustomers>
    </xsl:template>
    

  3. Save and close the XSL file.
  4. Remove the project XSLSamplesApp from the server.
  5. Add the project back to the server.
  6. Select XSLMediationComponent in the module assembly diagram, right-click, and select Test component.
  7. In the Component Test window, select the Configuration tab and remove MyServiceComponent from the list of emulators. Switch back to the Events tab.
  8. Enter the same input data as in the previous test: three customer elements under inCustomers, two of which have the role of manager.

    You may select inCustomers, right-click, and select Use value from pool to load the previously saved data.

  9. Click Continue. The return value should now contain only two elements whose role is a manager.

Figure 9. Component test output for content-based copy of array elements
Component test output for content-based copy

Create a second mediation flow

You can use the XSLT string concat function to concatenate two input strings into a target while copying other elements at the same time. We will create a second mediation flow implementation to demonstrate this feature:

  1. In the Business Integration view under the XSLSamples module, select Mediation Logic => Flows, right-click, and select New => Mediation flow.
  2. Enter XSLFunction in the Name field and click Next.
  3. Add MyService interface as both source and target interface and click Finish, which opens the new mediation flow in the editor.
  4. In the Mediation Flow Editor, map the send operation of MyService to the send operation of MyServicePartner.
  5. Add an XSL transformation primitive in the request flow of the Mediation Flow Editor.
  6. Connect the out terminal of MyService_send_input to the in terminal of the XSL transformation primitive.
  7. Connect the out terminal of the XSL transformation primitive to the in terminal of the MyServicePartner_send_Callout.
  8. Select the XSL Transformation and open the Properties Editor window in the bottom pane.
  9. From the Details view of the Properties of the XSL transformation, click New, which opens a new XSL mapping in the Visual Mapping Editor.

Apply a string concat XSLT function on the first array element

You can use XSLT functions on all elements, the first element only, required elements only, or selected elements of an array based on XML content. To apply an XSLT function to the first element of the array in the Mapping Editor:

  1. In the Source pane, select both id and name (hold down the Ctrl key when selecting the second item). Drag the selection to the name field in the Target pane. A mapping should be created, as indicated by the small triangle-shaped arrows. The mapping must now be modified to use an XPath string concat function.
  2. Under the Overview section in the Target pane, select the name field, right-click, and select Define XSLT function:

    Figure 10. Defining an XSLT function for mapping
    XSL  function 1

  3. Select string as the type of function and click Next.
  4. If not already selected, use the dropdown menu to select the concat function.
  5. We would like to insert a character ‘>’ between the name and id, so click Add to add a literal as a third input.
  6. In the Value Dialog, enter a ‘> ‘character (enclosed in single quotation marks) as parameter value.
  7. Click OK to add the above string literal as an Input parameter.
  8. Click Up and/or Down to change the order. The order of the three parameters should be name, ‘>’ character (literal), and then id:

    Figure 11. Specifying parameters for an XSLT Function
    XSL Function 3

  9. Click Finish. The concat function should now be visible in the Overview pane.
  10. Add two more mappings of source id to target id, and source role to target role. We are not mapping the customer[0*], so only the first element will be copied, as noted above.
  11. Save the mapping. In the Detail view of the Properties editor for the XSL transformation, click Regenerate XSL to generate the XSL file.
  12. Save and close the Mediation Flow Editor.

Now implement the response flow:

  1. Select the Response: send tab of the Mediation Flow Editor to open the response flow diagram. Connect the out terminal of MyServicePartner_send_CalloutResponse to the in terminal of MyService_send_InputResponse.
  2. Save and close the Mediation Flow Editor.

Switch implementation for the mediation component

Modify the sample mediation component to use a new mediation flow that uses XSL transformation with XSLT functions as its implementation:

  1. From the assembly editor, select XSLMediationComponent, right-click, and select implementation.
  2. Select the newly created flow XSLFunction as implementation and click OK.
  3. Save the module assembly diagram.
  4. Remove and then add XSLSamplesApp to the WebSphere ESB server.
  5. Now, test XSLMediationComponent using the component test, using the same input data as in the previous test. The return value should look like this:

Figure 12. Output values from component test
Test Output 2

Copy array elements and apply a concat XSLT function based on content

  1. Repeat the steps in the section Apply a string concat XSL function on the first array element, except for the following deviation: in specifying parameters to be used for evaluation of the XSLT function, use relative XPath expression from customer element. The parameter specifications should look like this:

    Figure 13. Specifying parameters with relative XPath for an XSLT Function
    XSL Function 2a

  2. In the XSL mapping editor, Drag customer[0*] from source to customer[0*] from target to iterate through all elements of the array:

    Figure 14. XSL Mapping editor
    XSL Function 2b

  3. Save the XSL Mapping Editor.
  4. From the Details view of the properties editor of the XSL transformation, click Regenerate XSL to regenerate the source XSL file.
  5. Click Edit to open the XSL source file. For selective copying and concatenation, change:
    <xsl:template name="inCustomers">
    	<inCustomers>
    		<xsl:apply-templates select="/body/send/inCustomers/customer"/>
    	</inCustomers>
    </xsl:template>
    

    to:

    <xsl:template name="inCustomers">
    	<inCustomers>
    		<xsl:apply-templates select="/body/send/inCustomers/customer[role='manager']"/>
    	</inCustomers>
    </xsl:template>
    

    The final XSL snippet should look like this:

    <xsl:template name="inCustomers">
    	<inCustomers>
    		<xsl:apply-templates select="/body/send/inCustomers/customer[role='manager']"/>
    	</inCustomers>
    </xsl:template>
    
    <!-- Composed element template -->
    <xsl:template match="customer">
    	<xsl:copy>
    		<id>
    			<xsl:value-of select="id/text()"/>
    		</id>
    		<name>
    			<xsl:value-of select="concat(name/text(), ' > ', id/text())"/>
    		</name>
    		<role>
    			<xsl:value-of select="role/text()"/>
    		</role>
    	</xsl:copy>
    </xsl:template>
    

  6. Remove XSLSamplesApp from the server, then add XSLSamplesApp back to the server.
  7. Test XSLMediationComponent as before, entering the same input parameters as before: customers array with three customer elements. This time, the return values should look like those in Figure 9 above.

Conclusion

This article has demonstrated some of the advanced features of the XSL transformation primitive in WebSphere ESB V6. The samples focus on how to deal with array data types and how to use XSLT functions. When you are not sure what the Mapping Editor is generating, you can always view the generated XSL source file. Some minor limitations in the Mapping Editor also require you to edit the generated XSL to implement some complex operations, and therefore some knowledge of XPath and XSLT is needed for such advanced transformations. For additional features not covered here such as XSL debugging, see the WebSphere Integration Developer V6 and Rational Application Developer V6 documentation.


Resources

About the author

Nay Lin photo

Nay Lin is a senior software engineer at the IBM Software Services for WebSphere Business Integration Proof-of-Concept Lab in Burlingame, California. He is an IBM certified IT specialist with extensive experience using WebSphere Business Integration products and developing J2EE and SOA applications using Rational Software Architect and WebSphere Integration Developer. You can contact Nay at naylin@us.ibm.com.

Comments (Undergoing maintenance)



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere
ArticleID=169372
ArticleTitle=Advanced XSL transformation mediation of arrays in WebSphere ESB
publish-date=10182006
author1-email=naylin@us.ibm.com
author1-email-cc=

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Rate a product. Write a review.

Special offers