You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 20 Next »

XPath

Camel supports XPath to allow an Expression or Predicate to be used in the DSL or Xml Configuration. For example you could use XPath to create an Predicate in a Message Filter or as an Expression for a Recipient List.

From 1.3 of Camel onwards you can use XPath expressions directly using smart completion in your IDE as follows:

from("queue:foo").
  filter().xpath("//foo")).
  to("queue:bar")
from("queue:foo").
  choice().xpath("//foo")).to("queue:bar").
  otherwise().to("queue:others");

Notice: The xpath is outside the filter node; after the ( ) braces.

In earlier versions of Camel you had to use the XPathBuilder methods then you can use the xpath() function inside your rules.

import static org.apache.camel.builder.xpath.XPathBuilder.*;
...
from("queue:foo").filter(xpath("//foo")).to("queue:bar")
import static org.apache.camel.builder.xpath.XPathBuilder.*;
...
from("queue:foo").choice(xpath("//foo")).to("queue:bar").
otherwise().to("queue:others");

Notice: The xpath is inside the filter node; within the ( ) braces.

Namespaces

In 1.3 onwards you can easily use namespaces with XPath expressions using the Namespaces helper class.

Namespaces ns = new Namespaces("c", "http://acme.com/cheese");

from("direct:start").filter().
    xpath("/c:person[@name='James']", ns).
    to("mock:result");

Using XML configuration

If you prefer to configure your routes in your Spring XML file then you can use XPath expressions as follows

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:foo="http://example.com/person"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
       http://activemq.apache.org/camel/schema/spring http://activemq.apache.org/camel/schema/spring/camel-spring.xsd">

  <camelContext id="camel" xmlns="http://activemq.apache.org/camel/schema/spring">
    <route>
      <from uri="activemq:MyQueue"/>
      <filter>
        <xpath>/foo:person[@name='James']</xpath>
        <to uri="mqseries:SomeOtherQueue"/>
      </filter>
    </route>
  </camelContext>
</beans>

Notice how we can reuse the namespace prefixes, foo in this case, in the XPath expression for easier namespace based XPath expressions!

Examples

Here is a simple example using an XPath expression as a predicate in a Message Filter

Error formatting macro: snippet: java.lang.NullPointerException

If you have a standard set of namespaces you wish to work with and wish to share them across many different XPath expressions you can use the NamespaceBuilder as shown in this example

Error formatting macro: snippet: java.lang.NullPointerException

In this sample we have a choice construct. The first choice evaulates if the message has a header key type that has the value Camel.
The 2nd choice evaluates if the message body has a name tag <name> which values is Kong.
If neither is true the message is routed in the otherwise block:

Error formatting macro: snippet: java.lang.NullPointerException

And the spring XML equivalent of the route:

Error formatting macro: snippet: java.lang.NullPointerException

XPath injection

You can use Bean Integration to invoke a method on a bean and use various languages such as XPath to extract a value from the message and bind it to a method parameter.

The default XPath annotation has SOAP and XML namespaces available. If you want to use your own namespace URIs in an XPath expression you can use your own copy of the XPath annotation to create whatever namespace prefixes you want to use.

i.e. cut and paste the XPath annotation code to your own project in a different package and/or annotation name then add whatever namespace prefix/uris you want in scope when you use your annotation on a method parameter. Then when you use your annotation on a method parameter all the namespaces you want will be available for use in your XPath expression.

For example

public class Foo {
	
    @MessageDriven(uri = "activemq:my.queue")
    public void doSomething(@Path("/foo/bar/text()") String correlationID, @Body String body) {
		// process the inbound message here
    }
}
  • No labels