12.3. Search a Collection of Simple Objects

Problem

You need to select objects from a Collection using XPath predicates.

Solution

Use Jakarta Commons JXPath to select objects from a Collection using predicates in XPath expressions. The iterate( ) method on JXPathContext takes an XPath expression and returns an Iterator that contains each node satisfying that expression. The following example uses simple XPath predicates to select Person objects from a List by age, first name, and position:

import org.apache.commons.jxpath.JXPathContext;

// Create a List of Person objects
List people = new ArrayList( );
people.add(new Person("Ahmad", "Russell", 28 );
people.add(new Person("Tom", "Russell", 35 );
people.add(new Person("Ahmad", "Abuzayedeh", 33 );

// Select all people older than 30
System.out.println( "** People older than 30");
JXPathContext context = JXPathContext.newContext( people );
Iterator iterator = context.iterate(".[@age > 30]");
printPeople(iterator);

// Select all people with a first name of 'Ahmad'
context = JXPathContext.newContext( people );
System.out.println( "** People with first name 'Ahmad'" );
iterator = context.iterate(".[@firstName = 'Ahmad']");
printPeople(iterator);

// Select the second person from the List
context = JXPathContext.newContext( people );
System.out.println( "** Third Person in List" );
Person p = (Person) context.getValue(".[2]");
System.out.println( "Person: " + p.getFirstName( ) + " " + p.getLastName( ) +
                    ", age: " + p.getAge( ) );

// A method to print out the result of each iteration.
private void printPeople(Iterator iterator) {
    while( iterator.hasNext( ) ) {
        Person p = (Person) iterator.next( );
        System.out.println( "Person: " + p.getFirstName( ) + 
            " " + p.getLastName( ) + ", age: " + p.getAge( ) );
    }
}

A JXPathContext is created by passing a List to newContext( ), and each expression is evaluated through a call to context.iterate(). Three expressions are evaluated, and the results of each expression are printed in the printPeople( ) method:

** People older than 30
Person: Tom Russell, age: 35
Person: Ahmad Abuzayedeh, age: 33

** People with first name 'Ahmad'
Person: Ahmad Russell, age: 28
Person: Ahmad Abuzayedeh, age: 33

** Second Person in List
Person: Tom Russell, age: 35

Discussion

The final expression in the previous example is a reference to a specific index in a List; .[2] selected the second element in the List supplied to the JXPathContext . Whenever an XPath expression deals with a property, which is a List or an array, a one-based index can be supplied in brackets after the name of the property. If a League object contains a List of Team objects, and a Team object contains a List of Player objects, the third Player object of the fourteenth Team can be selected by using the XPath expression league/teams[14]/players[3].

In the previous example, which filtered a List of Person objects, you might have noticed that the properties age and firstName are referenced as attributes in the XPath predicate expression. A property can be referenced either as an element or an attribute. In XPath terms, when JXPath resolves properties on an object, the child and attribute axis both reference properties. This means that the expressions .[@age > 30] and .[age > 30] would return the same results, as age can be addressed as a child element or attribute of the current node.

iterate( ) returns an Iterator that lets you iterate over all nodes that satisfy the given XPath query. getValue( ) returns the first matching result. In the previous example, iterate( ) retrieves two Person objects with an age property greater than 30. If the same expression were evaluated with getValue( ), only one Person object would have been returned: Tom Russell. Use iterate( ) when multiple nodes may match an XPath expression.

See Also

Chapter 5 demonstrates the use of Commons Collections’ CollectionUtils to select items in a Collection that satisfy a Predicate. For more information about using Predicate objects to filter collections, refer to Recipe 5.4.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.217.150.123