Class JXPathContext
- Direct Known Subclasses:
JXPathContextReferenceImpl
JXPathContext allows alternative implementations. This is why instead of
allocating JXPathContext directly, you should call a static
newContext
method. This method will utilize the
JXPathContextFactory
API to locate a suitable implementation of
JXPath. Bundled with JXPath comes a default implementation called Reference
Implementation.
JXPath Interprets XPath Syntax on Java Object Graphs
JXPath uses an intuitive interpretation of the xpath syntax in the context of Java object graphs. Here are some examples:Example 1: JavaBean Property Access
JXPath can be used to access properties of a JavaBean.In this example, we are using JXPath to access a property of thepublic class Employee { public String getFirstName(){ ... } } Employee emp = new Employee(); ... JXPathContext context = JXPathContext.newContext(emp); String fName = (String)context.getValue("firstName");
emp
bean. In this simple case the invocation of JXPath is
equivalent to invocation of getFirstName() on the bean.
Example 2: Nested Bean Property Access
JXPath can traverse object graphs:In this case XPath is used to access a property of a nested bean.public class Employee { public Address getHomeAddress(){ ... } } public class Address { public String getStreetNumber(){ ... } } Employee emp = new Employee(); ... JXPathContext context = JXPathContext.newContext(emp); String sNumber = (String)context.getValue("homeAddress/streetNumber");
A property identified by the xpath does not have to be a "leaf" property. For instance, we can extract the whole Address object in above example:
Address addr = (Address)context.getValue("homeAddress");
Example 3: Collection Subscripts
JXPath can extract elements from arrays and collections.A collection can be an arbitrary array or an instance of java.util. Collection.public class Integers { public int[] getNumbers(){ ... } } Integers ints = new Integers(); ... JXPathContext context = JXPathContext.newContext(ints); Integer thirdInt = (Integer)context.getValue("numbers[3]");
Note: in XPath the first element of a collection has index 1, not 0.
Example 4: Map Element Access
JXPath supports maps. To get a value use its key.Often you will need to use the alternative syntax for accessing Map elements:public class Employee { public Map getAddresses(){ return addressMap; } public void addAddress(String key, Address address){ addressMap.put(key, address); } ... } Employee emp = new Employee(); emp.addAddress("home", new Address(...)); emp.addAddress("office", new Address(...)); ... JXPathContext context = JXPathContext.newContext(emp); String homeZipCode = (String)context.getValue("addresses/home/zipCode");
In this case, the key can be an expression, e.g. a variable.String homeZipCode = (String) context.getValue("addresses[@name='home']/zipCode");
Note: At this point JXPath only supports Maps that use strings for keys.
Note: JXPath supports the extended notion of Map: any object with dynamic properties can be handled by JXPath provided that its class is registered with the
JXPathIntrospector
.
Example 5: Retrieving Multiple Results
JXPath can retrieve multiple objects from a graph. Note that the method called in this case is notgetValue
, but iterate
.
This returns a list of at most three books from the array of all books written by the author.public class Author { public Book[] getBooks(){ ... } } Author auth = new Author(); ... JXPathContext context = JXPathContext.newContext(auth); Iterator threeBooks = context.iterate("books[position() < 4]");
Example 6: Setting Properties
JXPath can be used to modify property values.public class Employee { public Address getAddress() { ... } public void setAddress(Address address) { ... } } Employee emp = new Employee(); Address addr = new Address(); ... JXPathContext context = JXPathContext.newContext(emp); context.setValue("address", addr); context.setValue("address/zipCode", "90190");
Example 7: Creating objects
JXPath can be used to create new objects. First, create a subclass ofAbstractFactory
and install it on the JXPathContext. Then
call createPathAndSetValue()
instead of
"setValue". JXPathContext will invoke your AbstractFactory when it discovers
that an intermediate node of the path is null. It will not override
existing nodes.
public class AddressFactory extends AbstractFactory { public boolean createObject(JXPathContext context, Pointer pointer, Object parent, String name, int index){ if ((parent instanceof Employee) && name.equals("address"){ ((Employee)parent).setAddress(new Address()); return true; } return false; } } JXPathContext context = JXPathContext.newContext(emp); context.setFactory(new AddressFactory()); context.createPathAndSetValue("address/zipCode", "90190");
Example 8: Using Variables
JXPath supports the notion of variables. The XPath syntax for accessing variables is "$varName".You can also set variables using JXPath:public class Author { public Book[] getBooks(){ ... } } Author auth = new Author(); ... JXPathContext context = JXPathContext.newContext(auth); context.getVariables().declareVariable("index", new Integer(2)); Book secondBook = (Book)context.getValue("books[$index]");
Note: you can only change the value of an existing variable this way, you cannot define a new variable.context.setValue("$index", new Integer(3));
When a variable contains a JavaBean or a collection, you can traverse the bean or collection as well:
... context.getVariables().declareVariable("book", myBook); String title = (String)context.getValue("$book/title); Book array[] = new Book[]{...}; context.getVariables().declareVariable("books", array); String title = (String)context.getValue("$books[2]/title);
Example 9: Using Nested Contexts
If you need to use the same set of variable while interpreting XPaths with different beans, it makes sense to put the variables in a separate context and specify that context as a parent context every time you allocate a new JXPathContext for a JavaBean.JXPathContext varContext = JXPathContext.newContext(null); varContext.getVariables().declareVariable("title", "Java"); JXPathContext context = JXPathContext.newContext(varContext, auth); Iterator javaBooks = context.iterate("books[title = $title]");
Using Custom Variable Pools
By default, JXPathContext creates a HashMap of variables. However, you can substitute a custom implementation of the Variables interface to make JXPath work with an alternative source of variables. For example, you can define implementations of Variables that cover a servlet context, HTTP request or any similar structure.Example 10: Using Standard Extension Functions
Using the standard extension functions, you can call methods on objects, static methods on classes and create objects using any constructor. The class names should be fully qualified.Here's how you can create new objects:
Here's how you can call static methods:Book book = (Book) context.getValue( "org.apache.commons.jxpath.example.Book.new ('John Updike')");
Here's how you can call regular methods:Book book = (Book) context.getValue( "org. apache.commons.jxpath.example.Book.getBestBook('John Updike')");
As you can see, the target of the method is specified as the first parameter of the function.String firstName = (String)context.getValue("getAuthorsFirstName($book)");
Example 11: Using Custom Extension Functions
Collections of custom extension functions can be implemented asFunctions
objects or as Java classes, whose methods
become extenstion functions.
Let's say the following class implements various formatting operations:
We can register this class with a JXPathContext:public class Formats { public static String date(Date d, String pattern){ return new SimpleDateFormat(pattern).format(d); } ... }
You can also register whole packages of Java classes using PackageFunctions.context.setFunctions(new ClassFunctions(Formats.class, "format")); ... context.getVariables().declareVariable("today", new Date()); String today = (String)context.getValue("format:date($today, 'MM/dd/yyyy')");
Also, see FunctionLibrary
, which is a class
that allows you to register multiple sets of extension functions with
the same JXPathContext.
Configuring JXPath
JXPath uses JavaBeans introspection to discover properties of JavaBeans. You can provide alternative property lists by supplying custom JXPathBeanInfo classes (seeJXPathBeanInfo
).
Notes
- JXPath does not support DOM attributes for non-DOM objects. Even though XPaths like "para[@type='warning']" are legitimate, they will always produce empty results. The only attribute supported for JavaBeans is "name". The XPath "foo/bar" is equivalent to "foo[@name='bar']".
. Also see XML Path Language (XPath) Version 1.0
You will also find more information and examples in JXPath User's Guide
- Version:
- $Revision: 652845 $ $Date: 2008-05-02 12:46:46 -0500 (Fri, 02 May 2008) $
-
Field Summary
FieldsModifier and TypeFieldDescriptionprivate static JXPathContext
protected Object
context beanprivate static JXPathContextFactory
protected HashMap
decimal format mapprotected AbstractFactory
AbstractFactoryprotected Functions
functionsprivate static final PackageFunctions
protected IdentityManager
IdentityManagerprotected KeyManager
KeyManagerprivate boolean
private boolean
private Locale
protected JXPathContext
parent contextprotected Variables
variables -
Constructor Summary
ConstructorsModifierConstructorDescriptionprotected
JXPathContext
(JXPathContext parentContext, Object contextBean) This constructor should remain protected - it is to be overridden by subclasses, but never explicitly invoked by clients. -
Method Summary
Modifier and TypeMethodDescriptionstatic CompiledExpression
Compiles the supplied XPath and returns an internal representation of the path that can then be evaluated.protected abstract CompiledExpression
compilePath
(String xpath) Overridden by each concrete implementation of JXPathContext to perform compilation.abstract Pointer
createPath
(String xpath) Creates missing elements of the path by invoking anAbstractFactory
, which should first be installed on the context by callingsetFactory(org.apache.commons.jxpath.AbstractFactory)
.abstract Pointer
createPathAndSetValue
(String xpath, Object value) The same as setValue, except it creates intermediate elements of the path by invoking anAbstractFactory
, which should first be installed on the context by callingsetFactory(org.apache.commons.jxpath.AbstractFactory)
.Returns the JavaBean associated with this context.private static JXPathContextFactory
Acquires a context factory and caches it.abstract Pointer
Returns a Pointer for the context bean.Get the named DecimalFormatSymbols.Returns the AbstractFactory installed on this context.Returns the set of functions installed on the context.Returns this context's identity manager.Returns this context's key manager.Returns the locale set with setLocale.Returns the namespace context pointer set withsetNamespaceContextPointer()
or, if none has been specified, the context pointer otherwise.getNamespaceURI
(String prefix) Given a prefix, returns a registered namespace URI.getNodeSetByKey
(String key, Object value) Locates a NodeSet by key/value.Returns the parent context of this context or null.abstract Pointer
getPointer
(String xpath) Traverses the xpath and returns a Pointer.getPointerByID
(String id) Locates a Node by its ID.getPointerByKey
(String key, String value) Locates a Node by a key value.Get the prefix associated with the specifed namespace URI.abstract JXPathContext
getRelativeContext
(Pointer pointer) Returns a JXPathContext that is relative to the current JXPathContext.abstract Object
Evaluates the xpath and returns the resulting object.abstract Object
Evaluates the xpath, converts the result to the specified class and returns the resulting object.Returns the variable pool associated with the context.boolean
Learn whether this JXPathContext is lenient.abstract Iterator
Traverses the xpath and returns an Iterator of all results found for the path.abstract Iterator
iteratePointers
(String xpath) Traverses the xpath and returns an Iterator of Pointers.static JXPathContext
newContext
(Object contextBean) Creates a new JXPathContext with the specified object as the root node.static JXPathContext
newContext
(JXPathContext parentContext, Object contextBean) Creates a new JXPathContext with the specified bean as the root node and the specified parent context.void
registerNamespace
(String prefix, String namespaceURI) Registers a namespace prefix.abstract void
Removes all elements of the object graph described by the xpath.abstract void
removePath
(String xpath) Removes the element of the object graph described by the xpath.selectNodes
(String xpath) Finds all nodes that match the specified XPath.selectSingleNode
(String xpath) Finds the first object that matches the specified XPath.void
setDecimalFormatSymbols
(String name, DecimalFormatSymbols symbols) SetsDecimalFormatSymbols
for a given name.void
setFactory
(AbstractFactory factory) Install an abstract factory that should be used by thecreatePath()
andcreatePathAndSetValue()
methods.void
setFunctions
(Functions functions) Install a library of extension functions.void
setIdentityManager
(IdentityManager idManager) Install an identity manager that will be used by the context to look up a node by its ID.void
setKeyManager
(KeyManager keyManager) Install a key manager that will be used by the context to look up a node by a key value.void
setLenient
(boolean lenient) If the context is in the lenient mode, then getValue() returns null for inexistent paths.void
Set the locale for this context.void
setNamespaceContextPointer
(Pointer namespaceContextPointer) Namespace prefixes can be defined implicitly by specifying a pointer to a context where the namespaces are defined.abstract void
Modifies the value of the property described by the supplied xpath.void
setVariables
(Variables vars) Installs a custom implementation of the Variables interface.
-
Field Details
-
contextFactory
-
compilationContext
-
GENERIC_FUNCTIONS
-
parentContext
parent context -
contextBean
context bean -
vars
variables -
functions
functions -
factory
AbstractFactory -
idManager
IdentityManager -
keyManager
KeyManager -
decimalFormats
decimal format map -
locale
-
lenientSet
private boolean lenientSet -
lenient
private boolean lenient
-
-
Constructor Details
-
JXPathContext
This constructor should remain protected - it is to be overridden by subclasses, but never explicitly invoked by clients.- Parameters:
parentContext
- parent contextcontextBean
- Object
-
-
Method Details
-
newContext
Creates a new JXPathContext with the specified object as the root node.- Parameters:
contextBean
- Object- Returns:
- JXPathContext
-
newContext
Creates a new JXPathContext with the specified bean as the root node and the specified parent context. Variables defined in a parent context can be referenced in XPaths passed to the child context.- Parameters:
parentContext
- parent contextcontextBean
- Object- Returns:
- JXPathContext
-
getContextFactory
Acquires a context factory and caches it.- Returns:
- JXPathContextFactory
-
getParentContext
Returns the parent context of this context or null.- Returns:
- JXPathContext
-
getContextBean
Returns the JavaBean associated with this context.- Returns:
- Object
-
getContextPointer
Returns a Pointer for the context bean.- Returns:
- Pointer
-
getRelativeContext
Returns a JXPathContext that is relative to the current JXPathContext. The supplied pointer becomes the context pointer of the new context. The relative context inherits variables, extension functions, locale etc from the parent context.- Parameters:
pointer
- Pointer- Returns:
- JXPathContext
-
setVariables
Installs a custom implementation of the Variables interface.- Parameters:
vars
- Variables
-
getVariables
Returns the variable pool associated with the context. If no such pool was specified with thesetVariables(org.apache.commons.jxpath.Variables)
method, returns the default implementation of Variables,BasicVariables
.- Returns:
- Variables
-
setFunctions
Install a library of extension functions.- Parameters:
functions
- Functions- See Also:
-
getFunctions
Returns the set of functions installed on the context.- Returns:
- Functions
-
setFactory
Install an abstract factory that should be used by thecreatePath()
andcreatePathAndSetValue()
methods.- Parameters:
factory
- AbstractFactory
-
getFactory
Returns the AbstractFactory installed on this context. If none has been installed and this context has a parent context, returns the parent's factory. Otherwise returns null.- Returns:
- AbstractFactory
-
setLocale
Set the locale for this context. The value of the "lang" attribute as well as the the lang() function will be affected by the locale. By default, JXPath usesLocale.getDefault()
- Parameters:
locale
- Locale
-
getLocale
Returns the locale set with setLocale. If none was set and the context has a parent, returns the parent's locale. Otherwise, returns Locale.getDefault().- Returns:
- Locale
-
setDecimalFormatSymbols
SetsDecimalFormatSymbols
for a given name. The DecimalFormatSymbols can be referenced as the third, optional argument in the invocation offormat-number (number,format,decimal-format-name)
function. By default, JXPath uses the symbols for the current locale.- Parameters:
name
- the format name or null for default format.symbols
- DecimalFormatSymbols
-
getDecimalFormatSymbols
Get the named DecimalFormatSymbols.- Parameters:
name
- key- Returns:
- DecimalFormatSymbols
- See Also:
-
setLenient
public void setLenient(boolean lenient) If the context is in the lenient mode, then getValue() returns null for inexistent paths. Otherwise, a path that does not map to an existing property will throw an exception. Note that if the property exists, but its value is null, the exception is not thrown.By default, lenient = false
- Parameters:
lenient
- flag
-
isLenient
public boolean isLenient()Learn whether this JXPathContext is lenient.- Returns:
- boolean
- See Also:
-
compile
Compiles the supplied XPath and returns an internal representation of the path that can then be evaluated. Use CompiledExpressions when you need to evaluate the same expression multiple times and there is a convenient place to cache CompiledExpression between invocations.- Parameters:
xpath
- to compile- Returns:
- CompiledExpression
-
compilePath
Overridden by each concrete implementation of JXPathContext to perform compilation. Is called bycompile()
.- Parameters:
xpath
- to compile- Returns:
- CompiledExpression
-
selectSingleNode
Finds the first object that matches the specified XPath. It is equivalent togetPointer(xpath).getNode()
. Note that this method produces the same result asgetValue()
on object models like JavaBeans, but a different result for DOM/JDOM etc., because it returns the Node itself, rather than its textual contents.- Parameters:
xpath
- the xpath to be evaluated- Returns:
- the found object
-
selectNodes
Finds all nodes that match the specified XPath.- Parameters:
xpath
- the xpath to be evaluated- Returns:
- a list of found objects
-
getValue
Evaluates the xpath and returns the resulting object. Primitive types are wrapped into objects.- Parameters:
xpath
- to evaluate- Returns:
- Object found
-
getValue
Evaluates the xpath, converts the result to the specified class and returns the resulting object.- Parameters:
xpath
- to evaluaterequiredType
- required type- Returns:
- Object found
-
setValue
Modifies the value of the property described by the supplied xpath. Will throw an exception if one of the following conditions occurs:- The xpath does not in fact describe an existing property
- The property is not writable (no public, non-static set method)
- Parameters:
xpath
- indicating positionvalue
- to set
-
createPath
Creates missing elements of the path by invoking anAbstractFactory
, which should first be installed on the context by callingsetFactory(org.apache.commons.jxpath.AbstractFactory)
.Will throw an exception if the AbstractFactory fails to create an instance for a path element.
- Parameters:
xpath
- indicating destination to create- Returns:
- pointer to new location
-
createPathAndSetValue
The same as setValue, except it creates intermediate elements of the path by invoking anAbstractFactory
, which should first be installed on the context by callingsetFactory(org.apache.commons.jxpath.AbstractFactory)
.Will throw an exception if one of the following conditions occurs:
- Elements of the xpath aleady exist, but the path does not in fact describe an existing property
- The AbstractFactory fails to create an instance for an intermediate element.
- The property is not writable (no public, non-static set method)
- Parameters:
xpath
- indicating position to createvalue
- to set- Returns:
- pointer to new location
-
removePath
Removes the element of the object graph described by the xpath.- Parameters:
xpath
- indicating position to remove
-
removeAll
Removes all elements of the object graph described by the xpath.- Parameters:
xpath
- indicating positions to remove
-
iterate
Traverses the xpath and returns an Iterator of all results found for the path. If the xpath matches no properties in the graph, the Iterator will be empty, but not null.- Parameters:
xpath
- to iterate- Returns:
- Iterator
-
getPointer
Traverses the xpath and returns a Pointer. A Pointer provides easy access to a property. If the xpath matches no properties in the graph, the pointer will be null.- Parameters:
xpath
- desired- Returns:
- Pointer
-
iteratePointers
Traverses the xpath and returns an Iterator of Pointers. A Pointer provides easy access to a property. If the xpath matches no properties in the graph, the Iterator be empty, but not null.- Parameters:
xpath
- to iterate- Returns:
- Iterator
-
setIdentityManager
Install an identity manager that will be used by the context to look up a node by its ID.- Parameters:
idManager
- IdentityManager to set
-
getIdentityManager
Returns this context's identity manager. If none has been installed, returns the identity manager of the parent context.- Returns:
- IdentityManager
-
getPointerByID
Locates a Node by its ID.- Parameters:
id
- is the ID of the sought node.- Returns:
- Pointer
-
setKeyManager
Install a key manager that will be used by the context to look up a node by a key value.- Parameters:
keyManager
- KeyManager
-
getKeyManager
Returns this context's key manager. If none has been installed, returns the key manager of the parent context.- Returns:
- KeyManager
-
getPointerByKey
Locates a Node by a key value.- Parameters:
key
- stringvalue
- string- Returns:
- Pointer found
-
getNodeSetByKey
Locates a NodeSet by key/value.- Parameters:
key
- stringvalue
- object- Returns:
- NodeSet found
-
registerNamespace
Registers a namespace prefix.- Parameters:
prefix
- A namespace prefixnamespaceURI
- A URI for that prefix
-
getNamespaceURI
Given a prefix, returns a registered namespace URI. If the requested prefix was not defined explicitly using the registerNamespace method, JXPathContext will then check the context node to see if the prefix is defined there. SeesetNamespaceContextPointer
.- Parameters:
prefix
- The namespace prefix to look up- Returns:
- namespace URI or null if the prefix is undefined.
-
getPrefix
Get the prefix associated with the specifed namespace URI.- Parameters:
namespaceURI
- the ns URI to check.- Returns:
- String prefix
- Since:
- JXPath 1.3
-
setNamespaceContextPointer
Namespace prefixes can be defined implicitly by specifying a pointer to a context where the namespaces are defined. By default, NamespaceContextPointer is the same as the Context Pointer, seegetContextPointer()
- Parameters:
namespaceContextPointer
- The pointer to the context where prefixes used in XPath expressions should be resolved.
-
getNamespaceContextPointer
Returns the namespace context pointer set withsetNamespaceContextPointer()
or, if none has been specified, the context pointer otherwise.- Returns:
- The namespace context pointer.
-