Oracle Service Bus 11g, Using Custom Xpath functions
May 10, 2010 17 Comments
In the new Oracle Service Bus 11g, Oracle gives us new functionality for the use of custom xpath functions.
These functions we eventually can re-use in for example the xslt or xquery transformations.
For this we need :
- 1. XML Configuration file (osb-custom.xml)
- 2. Property file (optional, osb-custom.properties)
- 3. Custom Function Class (jar package)
All these files need to be stored at the next location
<OSB_HOME>/config/xpath-functions
1. XML Configuration file
Create a new XML configuration file. I made a copy of the default file, osb-built-in.xml, edit that one, and change the settings.
<?xml version="1.0" encoding="UTF-8"?>
<xpf:xpathFunctions xmlns:xpf="http://www.bea.com/wli/sb/xpath/config">
<xpf:category id="%OSB_FUNCTIONS%">
<xpf:function>
<xpf:name>customConcat</xpf:name>
<xpf:comment>%FUNC_CUSTOM_CONCAT_COMMENT%</xpf:comment>
<xpf:namespaceURI>http://nl.iteye/osb/custom/functions/OsbUtils</xpf:namespaceURI>
<xpf:className>nl.iteye.osb.custom.functions.OsbUtils</xpf:className>
<xpf:method>java.lang.String customConcat(java.lang.String, java.lang.String)</xpf:method>
<xpf:isDeterministic>false</xpf:isDeterministic>
<xpf:scope>Pipeline</xpf:scope>
<xpf:scope>SplitJoin</xpf:scope>
</xpf:function>
</xpf:category>
</xpf:xpathFunctions>
A few notes on this file.
- category, the name of the category how it will appear in the IDE or Console
- function:name,comments, the description of the function how it will appear in the IDE or Console
- namespaceURI, the namespace which will be imported in for example the xquery to identify the custom function
- className, the java implementation of our custom xpath function
- method, the name of the method which we will be using for the implentation of the function
- isDeterministic, A value of true or false declaring whether or not the function is deterministic, the XQuery standard recommends the function to be deterministic (see documentation for further information)
- scope, i assume the scope of the OSB flow in which the function can be used
2. Property file
%OSB_FUNCTIONS%=Service Bus Functions
%FUNC_CUSTOM_CONCAT_COMMENT%=Returns the concat of the first and the second parameter
Not much in here,just a few placeholders for the descriptions
3. Custom Function Class
Create a new Java project in your favorite IDE. Create a new package and java class. For this demo i created a custom concat function which will concat parameter1 and parameter2 and return the result.
package nl.iteye.osb.custom.functions;
public class OsbUtils {
public OsbUtils() {
}
public static String customConcat(String firstParam, String secondParam) {
return firstParam + " " + secondParam;
}
}
The method needs to be defined as static.
Compile the code and create a jar archive and store this at the location mentioned in the top of the article.
After this we should have 3 extra files in this directory :
- osb-custom.xml
- osb-custom.properties
- osb-custom.jar
Restart the server, so the Oracle Service Bus will load the custom classes we just created. Check the output of the console to see if don’t see any errors come by. Wrong configuration (wrong methodname,package, etc) will end up with a little stacktrace in here.
Testing
To test the custom xpath function, create a new Oracle Service Bus project in Eclipse.
Add new XML Schema
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/NewXMLSchema" xmlns:tns="http://www.example.org/NewXMLSchema" elementFormDefault="qualified">
<element name="Input" type="tns:InputType"></element>
<element name="Output" type="string"></element>
<complexType name="InputType">
<sequence>
<element name="Name1" type="string"></element>
<element name="Name2" type="string"></element>
</sequence>
</complexType>
</schema>
Add new XQuery Transformation
In the list of expression functions we will see our custom function (customConcat)

(:: pragma bea:global-element-parameter parameter="$input1" element="ns0:Input" location="NewXMLSchema.xsd" ::)
(:: pragma bea:global-element-return element="ns0:Output" location="NewXMLSchema.xsd" ::)
declare namespace ns0 = "http://www.example.org/NewXMLSchema";
declare namespace xf = "http://tempuri.org/OSB%20Project%201/InputToOutput/";
declare function xf:InputToOutput($input1 as element(ns0:Input))
as element(ns0:Output) {
<ns0:Output>{ osbK3:customConcat($input1/ns0:Name1,$input1/ns0:Name2) }</ns0:Output>
};
declare variable $input1 as element(ns0:Input) external;
xf:InputToOutput($input1)
In the transformation i will map both the Name1 and Name2 to the input of the custom function, which will return the concat of both in output.
The easiest way to test the result is by running the XQuery on a connected server. Right mouseclick on the .xq file > Run As > Run on Server
The Oracle Service Bus Test Console will pop up.
Fill in the input data and execute.


Fantastic article.
One question, why prefix is osbk3? Is possible to change this?
Thanks!
You could add your own prefix
declare namespace test1 = “http://nl.iteye/osb/custom/functions/OsbUtils”;
and then use : test1:customConcat()
Did it work for you ?
Yes it did. I’m to happy
great
Yes, it works.
But i need to declare namespace in all XQuery Transformations. It’s possible declare global namespace? For example, fn-bea prefix it’s general for all XQuerys….
Thanks!
I have a similar problem. I can not set the custom prefix. Did you found a solution?
Does it work for 10.3 as well?
No. It’s new in the 11g release.
Eric, thank you for great article!
To everybody struggling to set custom default prefix: Boys, this is Oracle! Its software usually covers 99% of your needs, but you just can’t implement that missing percent no matter effort you dedicate.
Yes it did. I’m too happy
Is it possible to hold these xqueries in Eclipse project?
Description Resource Path Location Type
line 4, column 5: {err}XQ0017: “{http://nl.iteye/osb/custom/functions/OsbUtils}customConcat”: unknown function (or number of arguments (2) is wrong) test_custom_xpath.xq line 4 ALSB Conflict
what do you mean by ‘hold’ ?
Hi Eric,
If i want to create a customized data type in java.
for example, you created a class called OsbUtils that includes a method “String customConcat”
I would like to know if i can return an Employee class for instance. Is possible doing that in osb ?
I tried to do it but in osb console raise an error.
Thank & regards,
MartÃn
I think you need to generate xml beans objects for that and include them in the jar.
See this post on my new blog : http://www.xenta.nl/blog/2011/08/29/oracle-service-bus-java-callouts-with-xmlobjects/
It just was I needed, Thank a lot for sharing.
Hi Eric,
Thanks for nice post,It is very helpful.I have a query regarding the prefix,If I add name space in Xq I am able to get custom prefix,but In my message flow there is no need of using XQ,just in assisgn activity I am using custom functions,in that case I am getting default prefix,how to set custom default prefix?Actually I tried in osb-custom.xml file we have the ” http://www.bea.com/xquery/xquery-functions” if we use this uri we getting fn:bea prefix other than this like in ur
sample http://nl.iteye/osb/custom/functions/OsbUtils prefix is came like osbk3 that is first 3 characters of class name two other characters.Is it possible to set custom prefix?
Thanks
Mani