Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migration of unmigrated content due to installation of a new plugin

...

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.

...

If the message body is stream based, which means the input is received by Camel as a stream, then you will only be able to read the content of the stream once. Oftentimes when using XPath as Message Filter or Content Based Router the data will be accessed multiple times. Therefore use Stream caching or convert the message body to a String beforehand. This makes it safe to be re-read multiple times.

...

...

Namespaces

You can easily use namespaces with XPath expressions using the Namespaces helper class. Wiki Markup{snippet:id=example|lang=java|url=camel/trunk/camel-core/src/test/java/org/apache/camel/processor/XPathWithNamespacesFilterTest.java}

Variables

Variables in XPath is defined in different namespaces. The default namespace is http://camel.apache.org/schema/spring.

...

Function

Argument

Type

Description

in:body

none

Object

Will return the IN message body.

in:header

the header name

Object

Will return the IN message header.

out:body

none

Object

Will return the OUT message body.

out:header

the header name

Object

Will return the OUT message header.

function:properties

key for property

String

Camel 2.5: To lookup a property using the Properties component (property placeholders).

function:simple

simple expression

Object

Camel 2.5: To evaluate a Simple expression.

...

Here's an example showing some of these functions in use. Wiki Markup{snippet:id=ex|lang=java|url=camel/trunk/camel-core/src/test/java/org/apache/camel/language/XPathFunctionTest.java}And the new functions introduced in Camel 2.5: Wiki Markup{snippet:id=ex|lang=java|url=camel/trunk/camel-core/src/test/java/org/apache/camel/builder/xml/XPathFunctionsTest.java}

Using XML Configuration

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

...

...

Notice how we can reuse the namespace prefixes, foo in this case, in the XPath expression for easier namespace based XPath expressions! See also this discussion on the mailinglist about using your own namespaces with XPath.

...

The XPath expression will return a result type using native XML objects such as org.w3c.dom.NodeList. But many times you want a result type to be a String. To do this you have to instruct the XPath which result type to use.

In Java DSL:

...

...

In Spring DSL you use the resultType attribute to provide a fully qualified classname:

...

...

In @XPath:
Available as of Camel 2.1

...

...

Where we use the XPath function concat to prefix the order name with foo-. In this case we have to specify that we want a String as result type so the concat function works.

...

Some users may have XML stored in a header. To apply an XPath statement to a header's value you can do this by defining the headerName attribute.

In XML DSL: Wiki Markup{snippet:id=e1|lang=xml|url=camel/trunk/components/camel-test-blueprint/src/test/resources/org/apache/camel/test/blueprint/xpath/XPathHeaderNameTest.xml}And in Java DSL you specify the headerName as the 2nd parameter as shown:

...

...

Examples

Here is a simple example using an XPath expression as a predicate in a Message Filter Wiki Markup{snippet:id=example|lang=java|url=camel/trunk/camel-core/src/test/java/org/apache/camel/processor/XPathFilterTest.java}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 Wiki Markup{snippet:id=example|lang=java|url=camel/trunk/camel-core/src/test/java/org/apache/camel/processor/XPathWithNamespaceBuilderFilterTest.java}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: Wiki Markup{snippet:id=e1|lang=java|url=camel/trunk/camel-core/src/test/java/org/apache/camel/builder/xml/XPathHeaderTest.java}And the spring XML equivalent of the route: Wiki Markup{snippet:id=example|lang=xml|url=camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/SpringXPathHeaderTest-context.xml}

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. Wiki Markup{snippet:id=example|lang=java|url=camel/trunk/camel-core/src/test/java/org/apache/camel/component/xslt/MyXPath.java}e.g., cut and paste upper 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.

Example:

...

...

Using XPathBuilder Without an Exchange

...

For example you can do something like this:

...

...

This will match the given predicate.

You can also evaluate for example as shown in the following three examples:

...

...

Evaluating with a String result is a common requirement and thus you can do it a bit simpler:

...

...

Using Saxon with XPathBuilder

...

You need to add camel-saxon as dependency to your project. It's now easier to use Saxon with the XPathBuilder which can be done in several ways as shown below. Where as the latter ones are the easiest ones.

Using a factory Wiki Markup{snippet:id=e1|lang=java|url=camel/trunk/components/camel-saxon/src/test/java/org/apache/camel/builder/saxon/XPathTest.java}Using the object model
unmigrated-inline-wiki-markup
{snippet:id=e2|lang=java|url=camel/trunk/components/camel-saxon/src/test/java/org/apache/camel/builder/saxon/XPathTest.java}The easy one Wiki Markup{snippet:id=e3|lang=java|url=camel/trunk/components/camel-saxon/src/test/java/org/apache/camel/builder/saxon/XPathTest.java}

Setting a Custom XPathFactory Using System Property

...

This unit test shows how this can be done to use Saxon instead: Wiki Markup{snippet:id=e4|lang=java|url=camel/trunk/components/camel-saxon/src/test/java/org/apache/camel/builder/saxon/XPathTest.java}Camel will log at INFO level if it uses a non default XPathFactory such as:

...

...

To use Apache Xerces you can configure the system property:

...

...

Enabling Saxon from Spring DSL

...

Similarly to Java DSL, to enable Saxon from Spring DSL you have three options:

Specifying the factory

...

...

Specifying the object model

...

...

Shortcut

...

...

Namespace Auditing to Aid Debugging

...

Every time a new XPath expression is created in the internal pool, Camel will log the namespace context of the expression under the org.apache.camel.builder.xml.XPathBuilder logger. Since Camel represents Namespace Contexts in a hierarchical fashion (parent-child relationships), the entire tree is output in a recursive manner with the following format:

...

...

Any of these options can be used to activate this logging:

  1. Enable TRACE logging on the org.apache.camel.builder.xml.XPathBuilder logger, or some parent logger such as org.apache.camel or the root logger.
  2. Enable the logNamespaces option as indicated in Auditing Namespaces, in which case the logging will occur on the INFO level.

...

AuditingNamespaces

Auditing namespaces

Camel is able to discover and dump all namespaces present on every incoming message before evaluating an XPath expression, providing all the richness of information you need to help you analyse and pinpoint possible namespace issues. To achieve this, it in turn internally uses another specially tailored XPath expression to extract all namespace mappings that appear in the message, displaying the prefix and the full namespace URI(s) for each individual mapping.

...

You can enable this option in Java DSL and Spring DSL.

Java DSL:

...

...

Spring DSL:

...

The result of the auditing will be appear at the INFO level under the org.apache.camel.builder.xml.XPathBuilder logger and will look like the following:

...

...

Loading Script from External Resource

...

You can externalize the script and have Camel load it from a resource such as: classpath:, file: or http:.
This is done using the following syntax: resource:scheme:location, e.g., to refer to a file on the classpath you can do:

...

Dependencies

The XPath language is part of camel-core.