MAIN arrow Tutorials-5.1 arrow doXSLTransform Tutorial (Advanced)

doXSLTransform Tutorial (Advanced)

Print E-mail

This tutorial covers the use of the XPath function doXslTransform and XSLT. doXSLTransform lets you use XSLT to transform process data. XSLT is a fully fledged XML Document Transformation Language and allows to go beyond what regular assignments can do. Simply put, XSLT allows you to transform one XML document into another XML document.

 

This tutorial is split into three parts:

- simple hello world example that demonstrates how doXslTransform could be used instead of what our hello world example uses.

- a more complex example that demonstrates how to add an element to an array (a.k.a. a Nodeset).

- an example that uses XForms to show how you use XSLT to assign data from one Dynamic XForm form control to another.

 

This tutorial assumes that you are familiar with basic modelling concepts such as modelling processes, creating mappings, deployment and execution. The first two examples focus only on the mapping of the transform activity. The third example uses a PIPA and PA. If you are not familiar with PIPA's and PA's you can refer to the tutorials on these subjects.

 

Designing People Initiating Processes

 

Designing Processes with People Activities

 

Download the supporting projects:

doxsltransform1

doxsltransform2

doxsltransform3

 

Hello World Example

This example demonstrates how doXslTransform can be used to concatenate a string with a process variable.

The Mapping

Hello World mapping

 

doXslTransform requires a minimum of 2 parameters. For more on additional parameters, see the Next Section (Add Item).
The first parameter is the path to the XSL stylesheet itself (from the root of the project). So if you have transform1.xsl located at the root of your project, you would use "/transform1.xsl". The second parameter is the document to be transformed. It can be any element in the mapper.

doXslTransform will return the transformed document. The engine will assign this document to the destination node. Any rule of assignment to a destination node applies here. In other words, this node needs to exist.

 

The stylesheet

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns1="http://bpms.intalio.com/bpms/basic-types"
version="1.0">
<xsl:output method="xml"/>

<xsl:template match="ns1:doXSLTransform1">
<xsl:element name="message" namespace="httphttp://bpms.intalio.com/bpms/basic-types">
<xsl:value-of select="concat(text(), ' World')"/>
</xsl:element>
</xsl:template>

</xsl:stylesheet>

This is a very simple XSL stylesheet in which we match the root element of the passed document:

<xsl:template match="ns1:doXSLTransform1">

Create an element that will contain the text from the passed document

<xsl:element name="message" namespace="httphttp://bpms.intalio.com/bpms/basic-types">

And insert the text contained in the passed document and concatenate 'World' to it:

<xsl:value-of select="concat(text(), ' World')"/>

 

 

The execution

This process behaves exactly like the regular Hello World sample. Passing "Hello" returns "Hello World". A bit of overkill in this case, but this is to demonstrate how doXslTransform behaves.

 

Now that we have the basics covered, let's move on to a more interesting example.

 

Add Item Example

This example demonstrates how doXslTransform can be used to add an item to an existing Nodeset, something a regular BPEL assignment can not do.

 

The Mapping

Add Item Mapping

 

The mapping is similar to the previous example. You need to specify which stylesheet to use as the first parameter ("/transform2.xsl") here. The second parameter is the nodeset where we want to an item. The first 2 parameters are always the same. Then you can pass as many pairs of "Parameter Name" / "Parameter Value" as required. In this example, we pass an extra "item" parameter, and its value, taken from the input message (doXSLTransform2). These extra parameters will be made available to the XSL Stylesheet as regular xsl:param.

 

The stylesheet

The stylesheet used in this example is as follows:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns1="http://bpms.intalio.com/bpms/basic-types"
version="1.0">
<xsl:output method="xml"/>

<xsl:param name="item" >
<error>item not initialized</error>
</xsl:param>

<xsl:template match="ns1:items">
<xsl:element name="items" namespace="httphttp://bpms.intalio.com/bpms/basic-types">
<xsl:copy-of select="ns1:item" />
<xsl:copy-of select="$item" />
</xsl:element>
</xsl:template>

</xsl:stylesheet>

The name attribute of the xsl:param should match the 3rd argument to doXslTransform. Then it is a simple matter of matching the <items> element in the source document:

<xsl:template match="ns1:items">

Recreate our same root element <items>

<xsl:element name="items" namespace="httphttp://bpms.intalio.com/bpms/basic-types">

copy the existing <item> element(s):

<xsl:copy-of select="ns1:item" />

and finally, add the extra item:

<xsl:copy-of select="$item" />

 

 

The execution

Once deployed this process can be executed from the Intalio|BPMS console.

Below you will find an example of a passed document and the corresponding output document.

At execution, given the following input:

<ns1:doXSLTransform2 xmlns:ns1="http://bpms.intalio.com/bpms/basic-types" xmlns="http://bpms.intalio.com/bpms/basic-types" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<ns1:items>
<ns1:item>a</ns1:item>
<ns1:item>b</ns1:item>
</ns1:items>
<ns1:item>zz</ns1:item>
</ns1:doXSLTransform2>

you'll obtain this result:

<doXSLTransform2_Response xmlns="http://bpms.intalio.com/bpms/basic-types">
<items xmlns="httphttp://bpms.intalio.com/bpms/basic-types">
<ns1:item xmlns:ns1="http://bpms.intalio.com/bpms/basic-types">a</ns1:item>
<ns1:item xmlns:ns1="http://bpms.intalio.com/bpms/basic-types">b</ns1:item>
<ns1:item xmlns:ns1="http://bpms.intalio.com/bpms/basic-types" xmlns="http://bpms.intalio.com/bpms/basic-types" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">zz</ns1:item>
</items>
</doXSLTransform2_Response>

 

 

XForms examples

This example shows how you can use XSLT when assigning data from one Dynamic XForm form control to another Dynamic XForm form control. In this particular example we are assigning data from a form containing a Text Input form control that is situated in a Table cell, to another form that contains a Radio Button form control.

 

The process used to demonstrate this functionality in this tutorial is called doXSLTransform3. The process is started by a PIPA. This PIPA's form is called candidatesEntry.xform. The form allows a user to enter in as many Usernames and Names as they want then start the process by clicking on the Start Process button. The form contains a Table form control called candidatesTable with two columns (Username and Name) and an undefined number of rows (initially two). Inside the cells are Text Input form controls, one called username and one called name. These controls allow the user to enter the information into the process.

 

Once the process has been started by the PIPA, a People Activity is implemented which uses the form called displaycandidates.xform. This form displays all the Usernames that the user entered and allows the user to select one of them. This basic form contains one Radio Button form control called Chosen_Candidates which has a dynamically generated list of items. These items each have a label (display name) and value (value of radio button selection). The label and value are assigned the data from the username and name Text Input form controls belonging to the candidatesEntry.xform (username to label, name to value).

 

This data assignment occurs with the assistance of XSLT. XSLT is essential as the number of rows in the candidatesTable table are dynamic and the number of rows directly corresponds to the number of items in the Chosen_Candidates Radio Button, so a direct mapping cannot be implemented.

 

Screenshot of the candidatesEntry.xform design.

candidatesentry.jpg

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Screenshot of the displaycandidates.xform design.

displaycandidates.jpg

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

The Mapping

xform_example.jpg

 

 

 

 

 

 

 

 

 

 

 

 

 

As in the Hello World example, we have just two parameters. The first parameter is the path to the XSL stylesheet itself candidateToDisplayCandidate.xsl. The second parameter is the document to be transformed.

 

The big difference is the style sheet:

 

The stylesheet

The stylesheet used in this example is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:candidatesEntry="http://example.com/candidatesEntry/xform"
xmlns:displaycandidates="http://example.com/displaycandidates/xform"
xmlns="http://example.com/displaycandidates/xform"
version="1.0">
<xsl:output method="xml" indent="yes"/>

<xsl:template match="//candidatesEntry:candidatesTables">
<displaycandidates:Chosen_Candidates_items>
<xsl:for-each select="//candidatesEntry:candidatesTable">
<displaycandidates:item>
<displaycandidates:label>
<xsl:value-of select="candidatesEntry:username"/>
</displaycandidates:label>
<displaycandidates:value>
<xsl:value-of select="candidatesEntry:name"/>
</displaycandidates:value>
</displaycandidates:item>
</xsl:for-each>
</displaycandidates:Chosen_Candidates_items>
</xsl:template>
</xsl:stylesheet>

After the namespace definitions we match all nodes of the specified element candidatesTables in the passed document. Note: we used "//" not "/". When "//" is used at the beginning of a location path, it means: select all nodes in the document of the specified type.

<xsl:template match="//candidatesEntry:candidatesTables">

Create the root element of the output document <Chosen_Candidates_items>

<displaycandidates:Chosen_Candidates_items>

For each <candidatesTable> element in the passed document, create a <item> element in the output document. Within the <item> element, create two more elements, <label> and <value>. Set <label> to be the value of the <username> element from the passed document and set <value> to be the value of the <name> element. Once this for-each select has completed,

there will be the same number of <item> elements in the output document as there are <candidatesTable> elements in the passed document.

Relating this to the two XForms, we

<xsl:for-each select="//candidatesEntry:candidatesTable">
<displaycandidates:item>
<displaycandidates:label>
<xsl:value-of select="candidatesEntry:username"/>
</displaycandidates:label>
<displaycandidates:value>
<xsl:value-of select="candidatesEntry:name"/>
</displaycandidates:value>
</displaycandidates:item>
</xsl:for-each>

The Execution

 

Once the process is deployed, login to Intalio|Workflow UI-FW and select the Processes Tab. Click on 'Enter Candidates'.

The candidatesEntry form will display.

Fill out the form with the values below and click on Start Process:

candidatesentry_screenshot.jpg

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Once the process has started. Click on the Refresh link. A new task will appear called 'Select Candidates'. Click on this task and the displaycandidates form will show with the following values:

displaycandidates_screenshot.jpg

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Make a selection by checking one of the radio buttons, then click on Complete. That's it. You have successfully run the Process and used XSLT to handle complex assignments.

 

For more information on XSLT, these resources may be of use:

Zvon XSLT Tutorial

w3schools XSLT Tutorial

XSLT Specification

 

Last Updated ( Nov 20 2008 )
  < Prev Next >