How to create Collection Extension Function
JXPath is a java library for Object Graph Navigation using the XPath syntax.
This requires the libraries commons-jxpath-1.3.jar, commons-beanutils.jar and commons-logging.jar to be in classpath.
The following example shows creating a collection extension function in JXPath.
package com.bethecoder.tutorials.jxpath.common;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Student {
private String name;
private int age;
private String hobby;
private List<String> nickNames = new ArrayList<String> () ;
public Student () {
}
public Student ( String name, int age, String hobby ) {
super () ;
this .name = name;
this .age = age;
this .hobby = hobby;
}
public Student ( String name, int age, String hobby, String [] nickNames ) {
super () ;
this .name = name;
this .age = age;
this .hobby = hobby;
this .nickNames = Arrays.asList ( nickNames ) ;
}
public String getName () {
return name;
}
public void setName ( String name ) {
this .name = name;
}
public int getAge () {
return age;
}
public void setAge ( int age ) {
this .age = age;
}
public String getHobby () {
return hobby;
}
public void setHobby ( String hobby ) {
this .hobby = hobby;
}
public List<String> getNickNames () {
return nickNames;
}
public void setNickNames ( List<String> nickNames ) {
this .nickNames = nickNames;
}
public String toString () {
return "Student[name = " + name + ", age = " + age + ", hobby = " + hobby + ", " + nickNames + "]" ;
}
}
package com.bethecoder.tutorials.jxpath.common;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class StudentClass {
private String name;
private List<String> subjects = new ArrayList<String> () ;
private List<Student> students = new ArrayList<Student> () ;
private Map<String, List<Student>> subjectStudentMap = new HashMap<String, List<Student>> () ;
public StudentClass ( String name ) {
super () ;
this .name = name;
}
public String getName () {
return name;
}
public void setName ( String name ) {
this .name = name;
}
public List<String> getSubjects () {
return subjects;
}
public void setSubjects ( List<String> subjects ) {
this .subjects = subjects;
}
public List<Student> getStudents () {
return students;
}
public void setStudents ( List<Student> students ) {
this .students = students;
}
public Map<String, List<Student>> getSubjectStudentMap () {
return subjectStudentMap;
}
public void setSubjectStudentMap ( Map<String, List<Student>> subjectStudentMap ) {
this .subjectStudentMap = subjectStudentMap;
}
}
package com.bethecoder.tutorials.jxpath.functions;
import java.util.Iterator;
import org.apache.commons.jxpath.NodeSet;
import org.apache.commons.jxpath.Pointer;
public class CollectionFunction {
/**
* The extension function.
*
* @param nodeSet Selected list of nodes
* @param nickName Additional parameter from XPath expression
* @return
*/
public static boolean contains ( NodeSet nodeSet, String nickName ){
Iterator<?> nickNameIt = nodeSet.getPointers () .iterator () ;
while ( nickNameIt.hasNext ()) {
Pointer nickNamePointer = ( Pointer ) nickNameIt.next () ;
//System.out.println(item.asPath());
if ( nickNamePointer.getValue () .equals ( nickName )){
return true ;
}
}
return false ;
}
}
package com.bethecoder.tutorials.jxpath;
import java.util.Arrays;
import org.apache.commons.jxpath.ClassFunctions;
import org.apache.commons.jxpath.JXPathContext;
import com.bethecoder.tutorials.jxpath.common.Student;
import com.bethecoder.tutorials.jxpath.common.StudentClass;
import com.bethecoder.tutorials.jxpath.functions.CollectionFunction;
public class CollectionExtensionFunctionTest {
/**
* @param args
*/
public static void main ( String [] args ) {
Student std1 = new Student ( "Sriram" , 2 , "Chess" , new String [] { "Sri" , "Ram" , "Bunny" , "Sweety" , "Honey" }) ;
Student std2 = new Student ( "Sudhakar" , 29 , "Cricket" , new String [] { "Venkat" , "Munna" , "Sudha" }) ;
Student std3 = new Student ( "Anuradha" , 2 , "Cooking" , new String [] { "Anu" , "Radha" }) ;
StudentClass stCls = new StudentClass ( "MPC" ) ;
stCls.setStudents ( Arrays.asList ( std1, std2, std3 )) ;
//Create JXPathContext with StudentClass instance as ROOT node
JXPathContext context = JXPathContext.newContext ( stCls ) ;
//Register class functions in 'abc' namespace
context.setFunctions ( new ClassFunctions ( CollectionFunction.class, "abc" )) ;
Student bunny = ( Student ) context.getValue ( "/students[abc:contains(nickNames, 'Bunny')]" ) ;
System.out.println ( bunny ) ;
Student anu = ( Student ) context.getValue ( "/students[abc:contains(nickNames, 'Anu')]" ) ;
System.out.println ( anu ) ;
}
}
It gives the following output,
Student[name = Sriram, age = 2, hobby = Chess, [Sri, Ram, Bunny, Sweety, Honey]]
Student[name = Anuradha, age = 2, hobby = Cooking, [Anu, Radha]]