Home > Software > XPath2 functions in Java

XPath2 functions in Java


Some time ago I wrote an article about how to implement custom functions in XSLT/XPath in order to bring XPath 2 functions to XSLT 1 engine in .Net. Now it’s Java turn. And this is actually much easier.

First of all, how do you define Java custom functions in XSLT. Opposed to .Net, no workaround is needed, you simply define a namespace for all the public static methods in a class. And then you can easily access all these methods.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xpath2="java:com.wordpress.beradrian.XPath2Utilities">
...
<!-- select the XHTML elements of which CSS class is 'one' or 'two' -->
<xsl:for-each select="descendant::*[xpath2:matches(string(@class), '(\b(one|two))*')]">
...
</xsl:stylesheet>

Now all you have to do is write the com.wordpress.beradrian.XPath2Utilities class and its static method – one of them is matches.

package com.wordpress.beradrian;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Emulates XPath2 functions extending XSLT 1.0. capabilities.
 */
public class XPath2Utilities {
	public static String replace(String input, String pattern, String replacement) {
		return input.replaceAll(pattern, replacement);
	}
	
	/**
	 * Matches an input string against a regular expression
	 * @param input
	 * @param pattern the regular expression pattern
	 * @return true if the input matches the given regular expression, false otherwise
	 */
	public static boolean matches(String input, String pattern) {
		try {
			Pattern p = Pattern.compile(pattern);
			Matcher m = p.matcher(input);
			return m.find();
		} catch (Exception e) {
			return false;	
		}
	}
	
	/**
	 * Compares two strings.
	 * @param first first string to compare
	 * @param second second string to compare
	 * @return a negative value if first string is lexicographically smaller than the second one, 
	 * 0 if they're equal and positive if first one is bigger than second one
	 */
	public static int compare(String first, String second) {
		return first.compareTo(second);
	}

	/**
	 * @param first the full string
	 * @param second the string to check if it is a suffix of the first one.
	 * @return true if the second string is a suffix for the first one 
	 */
	public boolean endsWith(String first, String second) {
		return first.endsWith(second);
	}	
}

And now let’s see how you can put the pieces together and test the result. I’m using Eclipse and starting with version 3.4 (I think, I’m using Indigo anyway) it has an XSLT debugger integrated. In Project Explorer view, right click on an XSLT file and select Run As … / XSL Transformation. Then choose the XML file and the XML result will be generated. As this is as any run/debug item you can easily configure it. Go to Run / Run configurations, select the Classpath tab and then add your project, the one containing the class com.wordpress.beradrian.XPath2Utilities. You can also check the log in Console view.

For reference you can check XPath functions 1 and 2.

Categories: Software
  1. John
    October 3, 2011 at 1:51 pm

    Great Example…

    But when I tried I got error with matches string function. The error means that I don’t have XPATH 2.0. Can you tell me how to get it working…

    Have a nice day
    John

  2. October 4, 2011 at 12:39 am

    Did you create the class above, added it to your classpath and then added xmlns:xpath2=”java:com.wordpress.beradrian.XPath2Utilities” into your XSLT? To make it work, you should practically follow all the steps in the article.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: