You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by dj...@apache.org on 2020/03/13 01:14:24 UTC

[camel] 16/18: auto-copies of component language files in their new location

This is an automated email from the ASF dual-hosted git repository.

djencks pushed a commit to branch issue-14698-rearrange-adocs
in repository https://gitbox.apache.org/repos/asf/camel.git

commit fd1970fd5b6bc684eeb9af8455452194c6a80129
Author: David Jencks <dj...@apache.org>
AuthorDate: Thu Mar 12 18:12:28 2020 -0700

    auto-copies of component language files in their new location
---
 docs/components/modules/languages/nav.adoc         |  20 +
 .../modules/languages/pages/bean-language.adoc     | 184 ++++++++
 .../modules/languages/pages/groovy-language.adoc   | 198 ++++++++
 .../languages/pages/hl7terser-language.adoc        | 136 ++++++
 .../modules/languages/pages/jsonpath-language.adoc | 341 ++++++++++++++
 .../modules/languages/pages/mvel-language.adoc     | 124 ++++++
 .../modules/languages/pages/ognl-language.adoc     | 131 ++++++
 .../modules/languages/pages/spel-language.adoc     | 161 +++++++
 .../modules/languages/pages/xpath-language.adoc    | 496 +++++++++++++++++++++
 .../modules/languages/pages/xquery-language.adoc   | 159 +++++++
 10 files changed, 1950 insertions(+)

diff --git a/docs/components/modules/languages/nav.adoc b/docs/components/modules/languages/nav.adoc
new file mode 100644
index 0000000..6f7f526
--- /dev/null
+++ b/docs/components/modules/languages/nav.adoc
@@ -0,0 +1,20 @@
+// this file is auto generated and changes to it will be overwritten
+// make edits in docs/*nav.adoc.template files instead
+
+* Languages
+** xref:constant-language.adoc[Constant Language]
+** xref:exchangeProperty-language.adoc[ExchangeProperty Language]
+** xref:file-language.adoc[File Language]
+** xref:header-language.adoc[Header Language]
+** xref:ref-language.adoc[Ref Language]
+** xref:simple-language.adoc[Simple Language]
+** xref:tokenize-language.adoc[Tokenize Language]
+** xref:bean-language.adoc[Bean method Language]
+** xref:groovy-language.adoc[Groovy Language]
+** xref:hl7terser-language.adoc[HL7 Terser Language]
+** xref:jsonpath-language.adoc[JsonPath Language]
+** xref:mvel-language.adoc[MVEL Language]
+** xref:ognl-language.adoc[OGNL Language]
+** xref:spel-language.adoc[SpEL Language]
+** xref:xpath-language.adoc[XPath Language]
+** xref:xquery-language.adoc[XQuery Language]
diff --git a/docs/components/modules/languages/pages/bean-language.adoc b/docs/components/modules/languages/pages/bean-language.adoc
new file mode 100644
index 0000000..f11c064
--- /dev/null
+++ b/docs/components/modules/languages/pages/bean-language.adoc
@@ -0,0 +1,184 @@
+[[bean-language]]
+= Bean method Language
+:page-source: components/camel-bean/src/main/docs/bean-language.adoc
+== Bean Language
+*Since Camel 1.3*
+
+The purpose of the Bean Language is to be able to implement an
+xref:manual::expression.adoc[Expression] or xref:manual::predicate.adoc[Predicate] using
+a simple method on a bean. The bean name is resolved using a xref:manual::registry.adoc[Registry], such as the
+xref:manual::spring.adoc[Spring] *`ApplicationContext`*, then a method is
+invoked to evaluate the xref:manual::expression.adoc[Expression] or
+xref:manual::predicate.adoc[Predicate]. If no method name is provided then one
+is chosen using the rules for xref:manual::bean-binding.adoc[Bean Binding];
+using the type of the message body and using any annotations on the bean
+methods.
+
+The xref:manual::bean-binding.adoc[Bean Binding] rules are used to bind the
+xref:manual::message.adoc[Message] Exchange to the method parameters; so you can
+annotate the bean to extract headers or other expressions such as
+xref:xpath-language.adoc[XPath] or xref:xquery-language.adoc[XQuery] from the message.
+
+== Bean Language options
+
+// language options: START
+The Bean method language supports 4 options, which are listed below.
+
+
+
+[width="100%",cols="2,1m,1m,6",options="header"]
+|===
+| Name | Default | Java Type | Description
+| ref |  | String | Reference to bean to lookup in the registry
+| method |  | String | Name of method to call
+| beanType |  | String | Class name of the bean to use
+| trim | true | Boolean | Whether to trim the value to remove leading and trailing whitespaces and line breaks
+|===
+// language options: END
+
+
+[[BeanLanguage-UsingBeanExpressionsinJava]]
+== Using Bean Expressions in Java
+
+[source,syntaxhighlighter-pre]
+----
+from("activemq:topic:OrdersTopic")
+  .filter().method("myBean", "isGoldCustomer")
+    .to("activemq:BigSpendersQueue");
+----
+
+[[BeanLanguage-UsingBeanExpressionsinSpringXML]]
+== Using Bean Expressions in Spring XML
+
+[source,syntaxhighlighter-pre]
+----
+<route>
+  <from uri="activemq:topic:OrdersTopic"/>
+  <filter>
+    <method ref="myBean" method="isGoldCustomer"/>
+    <to uri="activemq:BigSpendersQueue"/>
+  </filter>
+</route>
+----
+
+[WARNING]
+====
+ **Bean Attribute Now Deprecated**
+
+The *`bean`* attribute of the method expression element is now
+deprecated. Use the *`ref`* attribute instead.
+
+====
+
+[[BeanLanguage-WritingtheExpressionBean]]
+== Writing the Expression Bean
+
+The bean in the above examples is just any old Java Bean with a method
+called *`isGoldCustomer()`* that returns some object that is easily
+converted to a *`boolean`* value in this case, as its used as a
+predicate.
+
+Example:
+
+[source,syntaxhighlighter-pre]
+----
+public class MyBean {
+  public boolean isGoldCustomer(Exchange exchange) {
+     // ...
+  }
+}
+----
+
+We can also use the xref:manual::bean-integration.adoc[Bean Integration]
+annotations.
+
+Example:
+
+[source,syntaxhighlighter-pre]
+----
+public boolean isGoldCustomer(String body) {...}
+----
+
+or
+
+[source,syntaxhighlighter-pre]
+----
+public boolean isGoldCustomer(@Header(name = "foo") Integer fooHeader) {...}
+----
+
+So you can bind parameters of the method to the Exchange, the
+xref:manual::message.adoc[Message] or individual headers, properties, the body
+or other expressions.
+
+[[BeanLanguage-Non-RegistryBeans]]
+== Non-Registry Beans
+
+The xref:bean-language.adoc[Bean Language] also supports invoking beans
+that isn't registered in the xref:manual::registry.adoc[Registry]. This is
+usable for quickly to invoke a bean from Java DSL where you don't need
+to register the bean in the xref:manual::registry.adoc[Registry] such as the
+xref:ROOT:spring.adoc[Spring] *`ApplicationContext`*. Camel can instantiate
+the bean and invoke the method if given a class or invoke an already
+existing instance.
+
+Example:
+
+[source,syntaxhighlighter-pre]
+----
+from("activemq:topic:OrdersTopic")
+  .filter().expression(BeanLanguage(MyBean.class, "isGoldCustomer"))
+  .to("activemq:BigSpendersQueue");
+----
+
+The 2nd parameter *`isGoldCustomer`* is an optional parameter to
+explicit set the method name to invoke. If not provided Camel will try
+to invoke the most suitable method. If case of ambiguity Camel will
+thrown an Exception. In these situations the 2nd parameter can solve
+this problem. Also the code is more readable if the method name is
+provided. The 1st parameter can also be an existing instance of a Bean
+such as:
+
+[source,syntaxhighlighter-pre]
+----
+private MyBean my;
+
+from("activemq:topic:OrdersTopic")
+  .filter().expression(BeanLanguage.bean(my, "isGoldCustomer"))
+  .to("activemq:BigSpendersQueue");
+----
+
+In *Camel 2.2*: you can avoid the *`BeanLanguage`* and have it just as:
+
+[source,syntaxhighlighter-pre]
+----
+private MyBean my;
+
+from("activemq:topic:OrdersTopic")
+  .filter().expression(bean(my, "isGoldCustomer"))
+  .to("activemq:BigSpendersQueue");
+----
+
+Which also can be done in a bit shorter and nice way:
+
+[source,syntaxhighlighter-pre]
+----
+private MyBean my;
+
+from("activemq:topic:OrdersTopic")
+  .filter().method(my, "isGoldCustomer")
+  .to("activemq:BigSpendersQueue");
+----
+
+[[BeanLanguage-OtherExamples]]
+== Other Examples
+
+We have some test cases you can look at if it'll help
+
+* https://github.com/apache/camel/blob/master/core/camel-core/src/test/java/org/apache/camel/processor/MethodFilterTest.java[MethodFilterTest]
+is a JUnit test case showing the Java xref:manual::dsl.adoc[DSL] use of the bean
+expression being used in a filter
+* https://github.com/apache/camel/blob/master/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/aggregator.xml[aggregator.xml]
+is a Spring XML test case for the xref:manual:eips:aggregate-eip.adoc[Aggregator] which
+uses a bean method call to test for the completion of the aggregation.
+
+include::camel-spring-boot::page$bean-starter.adoc[]
diff --git a/docs/components/modules/languages/pages/groovy-language.adoc b/docs/components/modules/languages/pages/groovy-language.adoc
new file mode 100644
index 0000000..59cf464
--- /dev/null
+++ b/docs/components/modules/languages/pages/groovy-language.adoc
@@ -0,0 +1,198 @@
+[[groovy-language]]
+= Groovy Language
+:page-source: components/camel-groovy/src/main/docs/groovy-language.adoc
+
+*Since Camel 1.3*
+
+Camel supports http://groovy.codehaus.org/[Groovy] among other
+Scripting Languages to allow an
+Expression or Predicate to be
+used in the DSL or xref:manual::xml-configuration.adoc[Xml
+Configuration].
+
+To use a Groovy expression use the following Java code
+
+[source,java]
+---------------------------------------
+... groovy("someGroovyExpression") ... 
+---------------------------------------
+
+For example you could use the *groovy* function to create an
+Predicate in a xref:manual:eips:filter-eip.adoc[Message Filter] or as an Expression for a
+Recipient List
+
+== Groovy Options
+
+
+
+// language options: START
+The Groovy language supports 1 options, which are listed below.
+
+
+
+[width="100%",cols="2,1m,1m,6",options="header"]
+|===
+| Name | Default | Java Type | Description
+| trim | true | Boolean | Whether to trim the value to remove leading and trailing whitespaces and line breaks
+|===
+// language options: END
+
+
+
+
+== Customizing Groovy Shell
+
+Sometimes you may need to use custom `GroovyShell` instance in your
+Groovy expressions. To provide custom `GroovyShell`, add implementation
+of the `org.apache.camel.language.groovy.GroovyShellFactory` SPI
+interface to your Camel registry. For example after adding the following
+bean to your Spring context...
+
+[source,java]
+----------------------------------------------------------------------
+public class CustomGroovyShellFactory implements GroovyShellFactory {
+ 
+  public GroovyShell createGroovyShell(Exchange exchange) {
+    ImportCustomizer importCustomizer = new ImportCustomizer();
+    importCustomizer.addStaticStars("com.example.Utils");
+    CompilerConfiguration configuration = new CompilerConfiguration();
+    configuration.addCompilationCustomizers(importCustomizer);
+    return new GroovyShell(configuration);
+  }
+
+}
+----------------------------------------------------------------------
+
+...Camel will use your custom GroovyShell instance (containing your
+custom static imports), instead of the default one.
+
+== Example
+
+[source,java]
+------------------------------------------------------------------------------------------------
+// lets route if a line item is over $100
+from("queue:foo").filter(groovy("request.lineItems.any { i -> i.value > 100 }")).to("queue:bar")
+------------------------------------------------------------------------------------------------
+
+And the Spring DSL:
+
+[source,xml]
+-----------------------------------------------------------------------------
+        <route>
+            <from uri="queue:foo"/>
+            <filter>
+                <groovy>request.lineItems.any { i -> i.value > 100 }</groovy>
+                <to uri="queue:bar"/>
+            </filter>
+        </route>
+-----------------------------------------------------------------------------
+
+== ScriptContext
+
+The JSR-223 scripting languages ScriptContext is pre configured with the
+following attributes all set at `ENGINE_SCOPE`:
+
+[width="100%",cols="10%,10%,80%",options="header",]
+|=======================================================================
+|Attribute |Type |Value
+
+|context |`org.apache.camel.CamelContext` |The Camel Context ( It cannot be used in groovy)
+
+|camelContext |`org.apache.camel.CamelContext` |The Camel Context
+
+|exchange |`org.apache.camel.Exchange` |The current Exchange
+
+|request |`org.apache.camel.Message` |The message (IN message)
+
+|response |`org.apache.camel.Message` |*Deprecated*: The OUT message. The OUT message if null by default. Use
+IN message instead.
+
+|properties |`org.apache.camel.builder.script.PropertiesFunction` |Function with a `resolve` method to make it easier to use
+Camels xref:ROOT:properties-component.adoc[Properties] component from scripts. See
+further below for example.
+|=======================================================================
+
+See Scripting Languages for the list of
+languages with explicit DSL support.
+
+== Additional arguments to ScriptingEngine
+
+*Since Camel 2.8*
+
+You can provide additional arguments to the `ScriptingEngine` using a
+header on the Camel message with the key `CamelScriptArguments`. +
+ See this example:
+
+== Using properties function
+
+*Since Camel 2.9*
+
+If you need to use the xref:ROOT:properties-component.adoc[Properties] component from a
+script to lookup property placeholders, then its a bit cumbersome to do
+so. 
+For example to set a header name myHeader with a value from a property
+placeholder, which key is provided in a header named "foo".
+
+[source,java]
+------------------------------------------------------------------------------------------------------------------------------
+.setHeader("myHeader").groovy(""context.resolvePropertyPlaceholders( + '{{' + request.headers.get(&#39;foo&#39;) + '}}' + ")")
+------------------------------------------------------------------------------------------------------------------------------
+
+You can use the properties function and the same example is simpler:
+
+[source,java]
+---------------------------------------------------------------------------------------
+.setHeader("myHeader").groovy("properties.resolve(request.headers.get(&#39;foo&#39;))")
+---------------------------------------------------------------------------------------
+
+== Loading script from external resource
+
+*Since Camel 2.11*
+
+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"`,
+eg to refer to a file on the classpath you can do:
+
+[source,java]
+-------------------------------------------------------------------
+.setHeader("myHeader").groovy("resource:classpath:mygroovy.groovy")
+-------------------------------------------------------------------
+
+== How to get the result from multiple statements script
+
+*Since Camel 2.14*
+
+As the scripteengine evale method just return a Null if it runs a
+multiple statments script. Camel now look up the value of script result
+by using the key of "result" from the value set. If you have multiple
+statements script, you need to make sure you set the value of result
+variable as the script return value.
+
+[source,text]
+-------------------------------------------------------------
+bar = "baz";
+# some other statements ... 
+# camel take the result value as the script evaluation result
+result = body * 2 + 1
+-------------------------------------------------------------
+
+== Dependencies
+
+To use scripting languages in your camel routes you need to add a
+dependency on *camel-groovy*.
+
+If you use Maven you could just add the following to your `pom.xml`,
+substituting the version number for the latest and greatest release (see
+the download page for the latest versions).
+
+[source,xml]
+---------------------------------------
+<dependency>
+  <groupId>org.apache.camel</groupId>
+  <artifactId>camel-groovy</artifactId>
+  <version>x.x.x</version>
+</dependency>
+---------------------------------------
+
+include::camel-spring-boot::page$groovy-starter.adoc[]
diff --git a/docs/components/modules/languages/pages/hl7terser-language.adoc b/docs/components/modules/languages/pages/hl7terser-language.adoc
new file mode 100644
index 0000000..474b48a
--- /dev/null
+++ b/docs/components/modules/languages/pages/hl7terser-language.adoc
@@ -0,0 +1,136 @@
+[[hl7terser-language]]
+= HL7 Terser Language
+:page-source: components/camel-hl7/src/main/docs/hl7terser-language.adoc
+
+*Since Camel 2.11*
+
+http://hl7api.sourceforge.net[HAPI] provides a
+http://hl7api.sourceforge.net/base/apidocs/ca/uhn/hl7v2/util/Terser.html[Terser]
+class that provides access to fields using a commonly used terse
+location specification syntax. The Terser language allows to use this
+syntax to extract values from messages and to use them as expressions
+and predicates for filtering, content-based routing etc.
+
+== HL7 Terser Language options
+
+// language options: START
+The HL7 Terser language supports 1 options, which are listed below.
+
+
+
+[width="100%",cols="2,1m,1m,6",options="header"]
+|===
+| Name | Default | Java Type | Description
+| trim | true | Boolean | Whether to trim the value to remove leading and trailing whitespaces and line breaks
+|===
+// language options: END
+
+
+== Samples:
+
+[source,java]
+----
+   import static org.apache.camel.component.hl7.HL7.hl7terser;
+
+   // extract patient ID from field QRD-8 in the QRY_A19 message above and put into message header
+   from("direct:test1")
+      .setHeader("PATIENT_ID", hl7terser("QRD-8(0)-1"))
+      .to("mock:test1");
+
+   // continue processing if extracted field equals a message header
+   from("direct:test2")
+      .filter(hl7terser("QRD-8(0)-1").isEqualTo(header("PATIENT_ID"))
+      .to("mock:test2");
+----
+
+== HL7 Validation predicate
+
+Often it is preferable to first parse a HL7v2 message and in a separate
+step validate it against a HAPI
+http://hl7api.sourceforge.net/base/apidocs/ca/uhn/hl7v2/validation/ValidationContext.html[ValidationContext].
+
+Sample:
+
+[source,java]
+----
+import static org.apache.camel.component.hl7.HL7.messageConformsTo;
+import ca.uhn.hl7v2.validation.impl.DefaultValidation;
+
+   // Use standard or define your own validation rules
+   ValidationContext defaultContext = new DefaultValidation();
+
+   // Throws PredicateValidationException if message does not validate
+   from("direct:test1")
+      .validate(messageConformsTo(defaultContext))
+      .to("mock:test1");
+----
+
+== HL7 Validation predicate using the HapiContext
+
+The HAPI Context is always configured with a
+http://hl7api.sourceforge.net/base/apidocs/ca/uhn/hl7v2/validation/ValidationContext.html[ValidationContext]
+(or a
+http://hl7api.sourceforge.net/base/apidocs/ca/uhn/hl7v2/validation/builder/ValidationRuleBuilder.html[ValidationRuleBuilder]),
+so you can access the validation rules indirectly. Furthermore, when
+unmarshalling the HL7DataFormat forwards the configured HAPI context in
+the `CamelHL7Context` header, and the validation rules of this context
+can be easily reused:
+
+[source,java]
+----
+import static org.apache.camel.component.hl7.HL7.messageConformsTo;
+import static org.apache.camel.component.hl7.HL7.messageConforms
+
+  HapiContext hapiContext = new DefaultHapiContext();
+  hapiContext.getParserConfiguration().setValidating(false); // don't validate during parsing
+
+  // customize HapiContext some more ... e.g. enforce that PID-8 in ADT_A01 messages of version 2.4 is not empty
+  ValidationRuleBuilder builder = new ValidationRuleBuilder() {
+      @Override
+      protected void configure() {
+         forVersion(Version.V24)
+              .message("ADT", "A01")
+              .terser("PID-8", not(empty()));
+         }
+      };
+  hapiContext.setValidationRuleBuilder(builder);
+
+  HL7DataFormat hl7 = new HL7DataFormat();
+  hl7.setHapiContext(hapiContext);
+
+  from("direct:test1")
+     .unmarshal(hl7)                // uses the GenericParser returned from the HapiContext
+     .validate(messageConforms())   // uses the validation rules returned from the HapiContext
+                                    // equivalent with .validate(messageConformsTo(hapiContext))
+     // route continues from here
+----
+
+== HL7 Acknowledgement expression
+
+A common task in HL7v2 processing is to generate an acknowledgement
+message as response to an incoming HL7v2 message, e.g. based on a
+validation result. The `ack` expression lets us accomplish this very
+elegantly:
+
+[source,java]
+----
+import static org.apache.camel.component.hl7.HL7.messageConformsTo;
+import static org.apache.camel.component.hl7.HL7.ack;
+import ca.uhn.hl7v2.validation.impl.DefaultValidation;
+
+  // Use standard or define your own validation rules
+   ValidationContext defaultContext = new DefaultValidation();
+
+   from("direct:test1")
+      .onException(Exception.class)
+         .handled(true)
+         .transform(ack()) // auto-generates negative ack because of exception in Exchange
+         .end()
+      .validate(messageConformsTo(defaultContext))
+      // do something meaningful here
+
+      // acknowledgement
+      .transform(ack())
+----
+
+include::camel-spring-boot::page$hl7-starter.adoc[]
diff --git a/docs/components/modules/languages/pages/jsonpath-language.adoc b/docs/components/modules/languages/pages/jsonpath-language.adoc
new file mode 100644
index 0000000..d9cf497
--- /dev/null
+++ b/docs/components/modules/languages/pages/jsonpath-language.adoc
@@ -0,0 +1,341 @@
+[[jsonpath-language]]
+= JsonPath Language
+:page-source: components/camel-jsonpath/src/main/docs/jsonpath-language.adoc
+
+*Since Camel 2.13*
+
+Camel supports https://code.google.com/p/json-path/[JSonPath] to allow
+using Expression or Predicate
+on json messages.
+
+[source,java]
+-----------------------------------------------------
+from("queue:books.new")
+  .choice()
+    .when().jsonpath("$.store.book[?(@.price < 10)]")
+      .to("jms:queue:book.cheap")
+    .when().jsonpath("$.store.book[?(@.price < 30)]")
+      .to("jms:queue:book.average")
+    .otherwise()
+      .to("jms:queue:book.expensive")
+-----------------------------------------------------
+
+== JSonPath Options
+
+
+// language options: START
+The JsonPath language supports 7 options, which are listed below.
+
+
+
+[width="100%",cols="2,1m,1m,6",options="header"]
+|===
+| Name | Default | Java Type | Description
+| resultType |  | String | Sets the class name of the result type (type from output)
+| suppressExceptions | false | Boolean | Whether to suppress exceptions such as PathNotFoundException.
+| allowSimple | true | Boolean | Whether to allow in inlined simple exceptions in the JsonPath expression
+| allowEasyPredicate | true | Boolean | Whether to allow using the easy predicate parser to pre-parse predicates.
+| writeAsString | false | Boolean | Whether to write the output of each row/element as a JSON String value instead of a Map/POJO value.
+| headerName |  | String | Name of header to use as input, instead of the message body
+| trim | true | Boolean | Whether to trim the value to remove leading and trailing whitespaces and line breaks
+|===
+// language options: END
+
+
+
+
+== Using XML configuration
+
+If you prefer to configure your routes in your Spring
+XML file then you can use xref:jsonpath-language.adoc[JSonPath] expressions as
+follows
+
+[source,xml]
+----
+<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
+  <route>
+    <from uri="direct:start"/>
+    <choice>
+      <when>
+        <jsonpath>$.store.book[?(@.price &lt; 10)]</jsonpath>
+        <to uri="mock:cheap"/>
+      </when>
+      <when>
+        <jsonpath>$.store.book[?(@.price &lt; 30)]</jsonpath>
+        <to uri="mock:average"/>
+      </when>
+      <otherwise>
+        <to uri="mock:expensive"/>
+      </otherwise>
+    </choice>
+  </route>
+</camelContext>
+----
+
+== Syntax
+
+See the https://code.google.com/p/json-path/[JSonPath] project page for
+further examples.
+
+== Easy Syntax
+
+*Since Camel 2.19*
+
+When you just want to define a basic predicate using jsonpath syntax it can be a bit hard to remember the syntax.
+ So for example to find out all the cheap books you have to do
+
+----
+$.store.book[?(@.price < 20)]
+----
+
+However what if you could just write it as
+
+----
+store.book.price < 20
+----
+
+And you can omit the path if you just want to look at nodes with a price key
+
+----
+price < 20
+----
+
+To support this there is a `EasyPredicateParser` which kicks-in if you have define the predicate
+  using a basic style. That means the predicate must not start with the `$` sign, and only include one operator.
+
+The easy syntax is:
+
+----
+left OP right
+----
+
+You can use Camel simple language in the right operator, eg
+
+----
+store.book.price < ${header.limit}
+----
+
+== Supported message body types
+
+Camel JSonPath supports message body using the following types:
+
+[width="100%",cols="3m,7",options="header"]
+|===
+| Type | Comment
+| File | Reading from files
+| String | Plain strings
+| Map | Message bodies as `java.util.Map` types
+| List | Message bodies as `java.util.List` types
+| POJO | *Optional* If Jackson is on the classpath, then camel-jsonpath
+  is able to use Jackson to read the message body as POJO and convert to `java.util.Map`
+  which is supported by JSonPath. For example you can add `camel-jackson` as dependency to include Jackson.
+| InputStream | If none of the above types matches, then Camel will attempt to read the message body as an `java.io.InputStream`.
+|===
+
+If a message body is of unsupported type then an exception is thrown by default, however you
+can configure JSonPath to suppress exceptions (see below)
+
+
+== Suppress exceptions
+
+*Since Camel 2.16*
+
+By default jsonpath will throw an exception if the json payload does not
+have a valid path accordingly to the configured jsonpath expression. In
+some use-cases you may want to ignore this in case the json payload
+contains optional data. Therefore you can set the option
+suppressExceptions to true to ignore this as shown:
+
+[source,java]
+----
+from("direct:start")
+    .choice()
+        // use true to suppress exceptions
+        .when().jsonpath("person.middlename", true)
+            .to("mock:middle")
+        .otherwise()
+            .to("mock:other");
+----
+
+And in XML DSL:
+
+[source,xml]
+----
+<route>
+  <from uri="direct:start"/>
+  <choice>
+    <when>
+      <jsonpath suppressExceptions="true">person.middlename</jsonpath>
+      <to uri="mock:middle"/>
+    </when>
+    <otherwise>
+      <to uri="mock:other"/>
+    </otherwise>
+  </choice>
+</route>
+----
+
+This option is also available on the `@JsonPath` annotation.
+
+== Inline Simple exceptions
+
+*Since Camel 2.18*
+
+Its now possible to inlined Simple language expressions in the JSonPath expression using the simple syntax $\{xxx\}.
+An example is shown below:
+
+[source,java]
+----
+from("direct:start")
+  .choice()
+    .when().jsonpath("$.store.book[?(@.price < ${header.cheap})]")
+      .to("mock:cheap")
+    .when().jsonpath("$.store.book[?(@.price < ${header.average})]")
+      .to("mock:average")
+    .otherwise()
+      .to("mock:expensive");
+----
+
+And in XML DSL:
+
+[source,xml]
+----
+<route>
+  <from uri="direct:start"/>
+  <choice>
+    <when>
+      <jsonpath>$.store.book[?(@.price < ${header.cheap})]</jsonpath>
+      <to uri="mock:cheap"/>
+    </when>
+    <when>
+      <jsonpath>$.store.book[?(@.price < ${header.average})]</jsonpath>
+      <to uri="mock:average"/>
+    </when>
+    <otherwise>
+      <to uri="mock:expensive"/>
+    </otherwise>
+  </choice>
+</route>
+----
+
+You can turn off support for inlined simple expression by setting the option allowSimple to false as shown:
+
+[source,java]
+----
+.when().jsonpath("$.store.book[?(@.price < 10)]", false, false)
+----
+
+And in XML DSL:
+
+[source,xml]
+----
+<jsonpath allowSimple="false">$.store.book[?(@.price < 10)]</jsonpath>
+----
+
+== JSonPath injection
+
+You can use Bean Integration to invoke a
+method on a bean and use various languages such as JSonPath to extract a
+value from the message and bind it to a method parameter.
+
+For example
+
+[source,java]
+----
+public class Foo {
+    
+    @Consume("activemq:queue:books.new")
+    public void doSomething(@JsonPath("$.store.book[*].author") String author, @Body String json) {
+      // process the inbound message here
+    }
+}
+----
+
+== Encoding Detection
+
+The encoding of the JSON document is
+detected automatically, if the document is encoded in unicode  (UTF-8,
+UTF-16LE, UTF-16BE, UTF-32LE, UTF-32BE ) as specified in  RFC-4627. If
+the encoding is a non-unicode encoding, you can either make sure that
+you enter the document in String format to the JSONPath component or you
+can specify the encoding in the header "*CamelJsonPathJsonEncoding*"
+(JsonpathConstants.HEADER_JSON_ENCODING).
+
+== Split JSon data into sub rows as JSon
+
+You can use jsonpath to split a JSon document, such as:
+
+[source,java]
+----
+from("direct:start")
+    .split().jsonpath("$.store.book[*]")
+    .to("log:book");
+----
+
+Then each book is logged, however the message body is a `Map` instance. Sometimes
+you may want to output this as plain String JSon value instead, which can be done
+with the `writeAsString` option as shown:
+
+[source,java]
+----
+from("direct:start")
+    .split().jsonpathWriteAsString("$.store.book[*]")
+    .to("log:book");
+----
+
+Then each book is logged as a String JSon value. For earlier versions of Camel you
+would need to use camel-jackson dataformat and marshal the message body to make it
+convert the message body from `Map` to a `String` type.
+
+== Using header as input
+*Since Camel 2.20*
+
+By default jsonpath uses the message body as the input source. However you can also use a header as input
+by specifying the `headerName` option.
+
+For example to count the number of books from a json document that
+was stored in a header named `books` you can do:
+
+[source,java]
+----
+from("direct:start")
+    .setHeader("numberOfBooks")
+        .jsonpath("$..store.book.length()", false, int.class, "books")
+    .to("mock:result");
+----
+
+In the `jsonpath` expression above we specify the name of the header as `books`
+and we also told that we wanted the result to be converted as an integer by `int.class`.
+
+The same example in XML DSL would be:
+
+[source,xml]
+----
+<route>
+  <from uri="direct:start"/>
+  <setHeader name="numberOfBooks">
+    <jsonpath headerName="books" resultType="int">$..store.book.length()</jsonpath>
+  </transform>
+  <to uri="mock:result"/>
+</route>
+----
+
+== Dependencies
+
+To use JSonPath in your camel routes you need to add the a dependency on
+*camel-jsonpath* which implements the JSonPath language.
+
+If you use maven you could just add the following to your pom.xml,
+substituting the version number for the latest & greatest release (see
+the download page for the latest versions).
+
+[source,xml]
+----
+<dependency>
+  <groupId>org.apache.camel</groupId>
+  <artifactId>camel-jsonpath</artifactId>
+  <version>x.x.x</version>
+</dependency>
+----
+
+include::camel-spring-boot::page$jsonpath-starter.adoc[]
diff --git a/docs/components/modules/languages/pages/mvel-language.adoc b/docs/components/modules/languages/pages/mvel-language.adoc
new file mode 100644
index 0000000..642668e
--- /dev/null
+++ b/docs/components/modules/languages/pages/mvel-language.adoc
@@ -0,0 +1,124 @@
+[[mvel-language]]
+= MVEL Language
+:page-source: components/camel-mvel/src/main/docs/mvel-language.adoc
+
+*Since Camel 2.0*
+
+Camel allows Mvel to be used as an Expression or
+Predicate the DSL or
+Xml Configuration.
+
+You could use Mvel to create an Predicate in a
+Message Filter or as an
+Expression for a
+Recipient List
+
+You can use Mvel dot notation to invoke operations. If you for instance
+have a body that contains a POJO that has a `getFamiliyName` method then
+you can construct the syntax as follows:
+
+[source,java]
+----------------------------------------
+"request.body.familyName"
+   // or 
+"getRequest().getBody().getFamilyName()"
+----------------------------------------
+
+== Mvel Options
+
+// language options: START
+The MVEL language supports 1 options, which are listed below.
+
+
+
+[width="100%",cols="2,1m,1m,6",options="header"]
+|===
+| Name | Default | Java Type | Description
+| trim | true | Boolean | Whether to trim the value to remove leading and trailing whitespaces and line breaks
+|===
+// language options: END
+
+
+== Variables
+
+[width="100%",cols="10%,10%,80%",options="header",]
+|=======================================================================
+|Variable |Type |Description
+
+|*this* |Exchange |the Exchange is the root object
+
+|exchange |Exchange |the Exchange object
+
+|exception |Throwable |the Exchange exception (if any)
+
+|exchangeId |String |the exchange id
+
+|fault |Message |the Fault message (if any)
+
+|request |Message |the exchange.in message
+
+|response |Message |the exchange.out message (if any)
+
+|properties |Map |the exchange properties
+
+|property(name) |Object |the property by the given name
+
+|property(name, type) |Type |the property by the given name as the given type
+|=======================================================================
+
+== Samples
+
+For example you could use Mvel inside a xref:manual:eips:filter-eip.adoc[Message
+Filter] in XML
+
+[source,java]
+---------------------------------------------
+<route>
+  <from uri="seda:foo"/>
+  <filter>
+    <mvel>request.headers.foo == 'bar'</mvel>
+    <to uri="seda:bar"/>
+  </filter>
+</route>
+---------------------------------------------
+
+And the sample using Java DSL:
+
+[source,java]
+---------------------------------------------------------------------------------
+   from("seda:foo").filter().mvel("request.headers.foo == 'bar'").to("seda:bar");
+---------------------------------------------------------------------------------
+
+== Loading script from external resource
+
+*Since Camel 2.11*
+
+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"`,
+eg to refer to a file on the classpath you can do:
+
+[source,java]
+-------------------------------------------------------------
+.setHeader("myHeader").mvel("resource:classpath:script.mvel")
+-------------------------------------------------------------
+
+== Dependencies
+
+To use Mvel in your camel routes you need to add the a dependency on
+*camel-mvel* which implements the Mvel language.
+
+If you use maven you could just add the following to your pom.xml,
+substituting the version number for the latest & greatest release (see
+the download page for the latest versions).
+
+[source,java]
+-------------------------------------
+<dependency>
+  <groupId>org.apache.camel</groupId>
+  <artifactId>camel-mvel</artifactId>
+  <version>x.x.x</version>
+</dependency>
+-------------------------------------
+
+include::camel-spring-boot::page$mvel-starter.adoc[]
diff --git a/docs/components/modules/languages/pages/ognl-language.adoc b/docs/components/modules/languages/pages/ognl-language.adoc
new file mode 100644
index 0000000..30d9ba7
--- /dev/null
+++ b/docs/components/modules/languages/pages/ognl-language.adoc
@@ -0,0 +1,131 @@
+[[ognl-language]]
+= OGNL Language
+:page-source: components/camel-ognl/src/main/docs/ognl-language.adoc
+
+*Since Camel 1.1*
+
+Camel allows http://commons.apache.org/proper/commons-ognl/[OGNL] to be
+used as an Expression or
+Predicate the DSL or
+Xml Configuration.
+
+You could use OGNL to create an Predicate in a
+Message Filter or as an
+Expression for a
+Recipient List
+
+You can use OGNL dot notation to invoke operations. If you for instance
+have a body that contains a POJO that has a `getFamilyName` method then
+you can construct the syntax as follows:
+
+[source,java]
+----------------------------------------
+"request.body.familyName"
+   // or 
+"getRequest().getBody().getFamilyName()"
+----------------------------------------
+
+== OGNL Options
+
+
+// language options: START
+The OGNL language supports 1 options, which are listed below.
+
+
+
+[width="100%",cols="2,1m,1m,6",options="header"]
+|===
+| Name | Default | Java Type | Description
+| trim | true | Boolean | Whether to trim the value to remove leading and trailing whitespaces and line breaks
+|===
+// language options: END
+
+
+
+
+== Variables
+
+[width="100%",cols="10%,10%,80%",options="header",]
+|=======================================================================
+|Variable |Type |Description
+
+|*this* |Exchange |the Exchange is the root object
+
+|exchange |Exchange |the Exchange object
+
+|exception |Throwable |the Exchange exception (if any)
+
+|exchangeId |String |the exchange id
+
+|fault |Message |the Fault message (if any)
+
+|request |Message |the exchange.in message
+
+|response |Message |the exchange.out message (if any)
+
+|properties |Map |the exchange properties
+
+|property(name) |Object |the property by the given name
+
+|property(name, type) |Type |the property by the given name as the given type
+|=======================================================================
+
+== Samples
+
+For example you could use OGNL inside a xref:manual:eips:filter-eip.adoc[Message
+Filter] in XML
+
+[source,java]
+---------------------------------------------
+<route>
+  <from uri="seda:foo"/>
+  <filter>
+    <ognl>request.headers.foo == 'bar'</ognl>
+    <to uri="seda:bar"/>
+  </filter>
+</route>
+---------------------------------------------
+
+And the sample using Java DSL:
+
+[source,java]
+---------------------------------------------------------------------------------
+   from("seda:foo").filter().ognl("request.headers.foo == 'bar'").to("seda:bar");
+---------------------------------------------------------------------------------
+
+== Loading script from external resource
+
+*Since Camel 2.11*
+
+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"`,
+eg to refer to a file on the classpath you can do:
+
+[source,java]
+------------------------------------------------------------
+.setHeader("myHeader").ognl("resource:classpath:myognl.txt")
+------------------------------------------------------------
+
+== Dependencies
+
+To use OGNL in your camel routes you need to add the a dependency on
+*camel-ognl* which implements the OGNL language.
+
+If you use maven you could just add the following to your pom.xml,
+substituting the version number for the latest & greatest release (see
+the download page for the latest versions).
+
+[source,java]
+-------------------------------------
+<dependency>
+  <groupId>org.apache.camel</groupId>
+  <artifactId>camel-ognl</artifactId>
+  <version>x.x.x</version>
+</dependency>
+-------------------------------------
+
+Otherwise, you'll also need
+https://repo1.maven.org/maven2/org/apache/servicemix/bundles/org.apache.servicemix.bundles.ognl/2.7.3_4/org.apache.servicemix.bundles.ognl-2.7.3_4.jar[OGNL]
+
+include::camel-spring-boot::page$ognl-starter.adoc[]
diff --git a/docs/components/modules/languages/pages/spel-language.adoc b/docs/components/modules/languages/pages/spel-language.adoc
new file mode 100644
index 0000000..f677b61
--- /dev/null
+++ b/docs/components/modules/languages/pages/spel-language.adoc
@@ -0,0 +1,161 @@
+[[spel-language]]
+= SpEL Language
+:page-source: components/camel-spring/src/main/docs/spel-language.adoc
+
+*Since Camel 2.7*
+
+Camel allows
+https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#expressions[Spring Expression Language (SpEL)]
+to be used as an Expression or Predicate in the DSL or XML Configuration.
+
+[NOTE]
+====
+It is recommended to use SpEL in Spring runtimes. However, you can
+use SpEL in other runtimes (there may be functionality SpEL cannot do when not running in a Spring runtime)
+====
+
+== Variables
+
+The following variables are available in expressions and predicates written in SpEL:
+
+[width="100%",cols="10%,10%,80%",options="header",]
+|===
+|Variable |Type |Description
+
+|this |Exchange |the Exchange is the root object
+
+|exchange |Exchange |the Exchange object
+
+|exception |Throwable |the Exchange exception (if any)
+
+|exchangeId |String |the exchange id
+
+|fault |Message |the Fault message (if any)
+
+|body |Object | The IN message body.
+
+|request |Message |the exchange.in message
+
+|response |Message |the exchange.out message (if any)
+
+|properties |Map |the exchange properties
+
+|property(name) |Object |the property by the given name
+
+|property(name, type) |Type |the property by the given name as the given type
+|===
+
+== Options
+
+// language options: START
+The SpEL language supports 1 options, which are listed below.
+
+
+
+[width="100%",cols="2,1m,1m,6",options="header"]
+|===
+| Name | Default | Java Type | Description
+| trim | true | Boolean | Whether to trim the value to remove leading and trailing whitespaces and line breaks
+|===
+// language options: END
+
+== Samples
+
+=== Expression templating
+
+SpEL expressions need to be surrounded by `#{` `}` delimiters since
+expression templating is enabled. This allows you to combine SpEL
+expressions with regular text and use this as extremely lightweight
+template language.
+
+For example if you construct the following route:
+
+[source,java]
+----
+from("direct:example")
+    .setBody(spel("Hello #{request.body}! What a beautiful #{request.headers['dayOrNight']}"))
+    .to("mock:result");
+----
+
+In the route above, notice spel is a static method which we need to
+import from `org.apache.camel.language.spel.SpelExpression.spel`, as we
+use spel as an Expression passed in as a parameter
+to the `setBody` method. Though if we use the fluent API we can do this
+instead:
+
+[source,java]
+----
+from("direct:example")
+    .setBody().spel("Hello #{request.body}! What a beautiful #{request.headers['dayOrNight']}")
+    .to("mock:result");
+----
+
+Notice we now use the `spel` method from the `setBody()` method. And
+this does not require us to static import the spel method from
+`org.apache.camel.language.spel.SpelExpression.spel`.
+
+And sent a message with the string "World" in the body, and a header
+"dayOrNight" with value "day":
+
+[source,java]
+----
+template.sendBodyAndHeader("direct:example", "World", "dayOrNight", "day");
+----
+
+The output on `mock:result` will be _"Hello World! What a beautiful
+day"_
+
+=== Bean integration
+
+You can reference beans defined in the Registry
+(most likely an `ApplicationContext`) in your SpEL expressions. For
+example if you have a bean named "foo" in your `ApplicationContext` you
+can invoke the "bar" method on this bean like this:
+
+[source,text]
+----
+#{@foo.bar == 'xyz'}
+----
+
+=== SpEL in enterprise integration patterns
+
+You can use SpEL as an expression for xref:manual:eips:recipientList-eip.adoc[Recipient
+List] or as a predicate inside a xref:manual:eips:filter-eip.adoc[Message
+Filter]:
+
+[source,xml]
+----
+<route>
+  <from uri="direct:foo"/>
+  <filter>
+    <spel>#{request.headers.foo == 'bar'}</spel>
+    <to uri="direct:bar"/>
+  </filter>
+</route>
+----
+
+And the equivalent in Java DSL:
+
+[source,java]
+----
+from("direct:foo")
+    .filter().spel("#{request.headers.foo == 'bar'}")
+    .to("direct:bar");
+----
+
+== Loading script from external resource
+
+*Since Camel 2.11*
+
+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"`,
+eg to refer to a file on the classpath you can do:
+
+[source,java]
+----
+.setHeader("myHeader").spel("resource:classpath:myspel.txt")
+----
+
+
+include::camel-spring-boot::page$spring-starter.adoc[]
diff --git a/docs/components/modules/languages/pages/xpath-language.adoc b/docs/components/modules/languages/pages/xpath-language.adoc
new file mode 100644
index 0000000..615c6da
--- /dev/null
+++ b/docs/components/modules/languages/pages/xpath-language.adoc
@@ -0,0 +1,496 @@
+[[xpath-language]]
+= XPath Language
+:page-source: components/camel-xpath/src/main/docs/xpath-language.adoc
+
+*Since Camel 1.1*
+
+Camel supports http://www.w3.org/TR/xpath[XPath] to allow an
+Expression or Predicate to be
+used in the DSL or xref:manual::xml-configuration.adoc[Xml
+Configuration]. For example you could use XPath to create an
+Predicate in a xref:manual:eips:filter-eip.adoc[Message
+Filter] or as an Expression for a
+Recipient List.
+
+*Streams*
+
+If the message body is stream based, which means the input it receives
+is submitted to Camel as a stream. That means you will only be able to
+read the content of the stream *once*. So often when you use
+xref:xpath-language.adoc[XPath] as xref:xpath-language.adoc[Message Filter] or
+Content Based Router then you need to
+access the data multiple times, and you should use
+Stream Caching or convert the message body to
+a `String` prior which is safe to be re-read multiple times.
+
+[source,java]
+----
+from("queue:foo").
+  filter().xpath("//foo")).
+  to("queue:bar")
+----
+
+[source,java]
+----
+from("queue:foo").
+  choice().xpath("//foo")).to("queue:bar").
+  otherwise().to("queue:others");
+----
+
+== XPath Language options
+
+// language options: START
+The XPath language supports 9 options, which are listed below.
+
+
+
+[width="100%",cols="2,1m,1m,6",options="header"]
+|===
+| Name | Default | Java Type | Description
+| documentType |  | String | Name of class for document type The default value is org.w3c.dom.Document
+| resultType | NODESET | String | Sets the class name of the result type (type from output) The default result type is NodeSet
+| saxon | false | Boolean | Whether to use Saxon.
+| factoryRef |  | String | References to a custom XPathFactory to lookup in the registry
+| objectModel |  | String | The XPath object model to use
+| logNamespaces | false | Boolean | Whether to log namespaces which can assist during trouble shooting
+| headerName |  | String | Name of header to use as input, instead of the message body
+| threadSafety | false | Boolean | Whether to enable thread-safety for the returned result of the xpath expression. This applies to when using NODESET as the result type, and the returned set has multiple elements. In this situation there can be thread-safety issues if you process the NODESET concurrently such as from a Camel Splitter EIP in parallel processing mode. This option prevents concurrency issues by doing defensive copies of the nodes. It is recommended to turn this option on i [...]
+| trim | true | Boolean | Whether to trim the value to remove leading and trailing whitespaces and line breaks
+|===
+// language options: END
+
+
+== Namespaces
+
+You can easily use namespaces with XPath expressions using the
+Namespaces helper class.
+
+== Variables
+
+Variables in XPath is defined in different namespaces. The default
+namespace is `\http://camel.apache.org/schema/spring`.
+
+[width="100%",cols="10%,10%,10%,70%",options="header",]
+|===
+|Namespace URI |Local part |Type |Description
+
+|http://camel.apache.org/xml/in/[http://camel.apache.org/xml/in/] |in |Message |the exchange.in message
+
+|http://camel.apache.org/xml/out/[http://camel.apache.org/xml/out/] |out |Message |the exchange.out message
+
+|http://camel.apache.org/xml/function/[http://camel.apache.org/xml/function/] |functions |Object |Additional functions
+
+|http://camel.apache.org/xml/variables/environment-variables[http://camel.apache.org/xml/variables/environment-variables] |env |Object |OS environment variables
+
+|http://camel.apache.org/xml/variables/system-properties[http://camel.apache.org/xml/variables/system-properties] |system |Object |Java System properties
+
+|http://camel.apache.org/xml/variables/exchange-property[http://camel.apache.org/xml/variables/exchange-property] |  | Object |the exchange property
+|===
+
+Camel will resolve variables according to either:
+
+* namespace given
+* no namespace given
+
+=== Namespace given
+
+If the namespace is given then Camel is instructed exactly what to
+return. However when resolving either *in* or *out* Camel will try to
+resolve a header with the given local part first, and return it. If the
+local part has the value *body* then the body is returned instead.
+
+=== No namespace given
+
+If there is no namespace given then Camel resolves only based on the
+local part. Camel will try to resolve a variable in the following steps:
+
+* from `variables` that has been set using the `variable(name, value)`
+fluent builder
+* from message.in.header if there is a header with the given key
+* from exchange.properties if there is a property with the given key
+
+== Functions
+
+Camel adds the following XPath functions that can be used to access the
+exchange:
+
+[width="100%",cols="10%,10%,10%,70%",options="header",]
+|===
+|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 |To lookup a property using the
+xref:ROOT:properties-component.adoc[Properties] component (property placeholders).
+
+|function:simple |simple expression |Object |To evaluate a xref:simple-language.adoc[Simple] expression.
+|===
+
+CAUTION: `function:properties` and `function:simple` is not supported
+when the return type is a `NodeSet`, such as when using with a
+Splitter EIP.
+
+Here's an example showing some of these functions in use.
+
+== Using XML configuration
+
+If you prefer to configure your routes in your Spring
+XML file then you can use XPath expressions as follows
+
+[source,xml]
+----
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+       http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
+
+  <camelContext id="camel" xmlns="http://activemq.apache.org/camel/schema/spring" xmlns:foo="http://example.com/person">
+    <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!
+
+See also this
+http://camel.465427.n5.nabble.com/fail-filter-XPATH-camel-td476424.html[discussion
+on the mailinglist] about using your own namespaces with xpath
+
+== Setting result type
+
+The xref:xpath-language.adoc[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
+xref:xpath-language.adoc[XPath] which result type to use.
+
+In Java DSL:
+
+[source,java]
+----
+xpath("/foo:person/@id", String.class)
+----
+
+In Spring DSL you use the *resultType* attribute to provide a fully
+qualified classname:
+
+[source,xml]
+----
+<xpath resultType="java.lang.String">/foo:person/@id</xpath>
+----
+
+In @XPath: +
+ *Since Camel 2.1*
+
+[source,java]
+----
+@XPath(value = "concat('foo-',//order/name/)", resultType = String.class) String name)
+----
+
+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.
+
+== Using XPath on Headers
+
+*Since Camel 2.11*
+
+Some users may have XML stored in a header. To apply an XPath to a
+header's value you can do this by defining the 'headerName' attribute.
+
+And in Java DSL you specify the headerName as the 2nd parameter as
+shown:
+
+[source,java]
+----
+  xpath("/invoice/@orderType = 'premium'", "invoiceDetails")
+----
+
+== Examples
+
+Here is a simple
+https://github.com/apache/camel/blob/master/camel-core/src/test/java/org/apache/camel/processor/XPathFilterTest.java[example]
+using an XPath expression as a predicate in a
+Message Filter
+
+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
+https://github.com/apache/camel/blob/master/camel-core/src/test/java/org/apache/camel/processor/XPathWithNamespaceBuilderFilterTest.java[in
+this example]
+
+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:
+
+And the spring XML equivalent of the route:
+
+== 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
+https://www.javadoc.io/doc/org.apache.camel/camel-xpath/current/org/apache/camel/language/xpath/XPath.html[XPath
+annotation] to create whatever namespace prefixes you want to use.
+
+i.e. 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.
+
+For example
+
+[source,java]
+----
+public class Foo {
+    
+    @MessageDriven(uri = "activemq:my.queue")
+    public void doSomething(@MyXPath("/ns1:foo/ns2:bar/text()") String correlationID, @Body String body) {
+        // process the inbound message here
+    }
+}
+----
+
+== Using XPathBuilder without an Exchange
+
+*Since Camel 2.3*
+
+You can now use the `org.apache.camel.builder.XPathBuilder` without the
+need for an Exchange. This comes handy if you want
+to use it as a helper to do custom xpath evaluations.
+
+It requires that you pass in a CamelContext
+since a lot of the moving parts inside the XPathBuilder requires access
+to the Camel Type Converter and hence why
+CamelContext is needed.
+
+For example you can do something like this:
+
+[source,java]
+----
+boolean matches = XPathBuilder.xpath("/foo/bar/@xyz").matches(context, "<foo><bar xyz='cheese'/></foo>"));
+----
+
+This will match the given predicate.
+
+You can also evaluate for example as shown in the following three
+examples:
+
+[source,java]
+----
+String name = XPathBuilder.xpath("foo/bar").evaluate(context, "<foo><bar>cheese</bar></foo>", String.class);
+Integer number = XPathBuilder.xpath("foo/bar").evaluate(context, "<foo><bar>123</bar></foo>", Integer.class);
+Boolean bool = XPathBuilder.xpath("foo/bar").evaluate(context, "<foo><bar>true</bar></foo>", Boolean.class);
+----
+
+Evaluating with a String result is a common requirement and thus you can
+do it a bit simpler:
+
+[source,java]
+----
+String name = XPathBuilder.xpath("foo/bar").evaluate(context, "<foo><bar>cheese</bar></foo>");
+----
+
+== Using Saxon with XPathBuilder
+
+*Since Camel 2.3*
+
+You need to add *camel-saxon* as dependency to your project.
+
+Its now easier to use http://saxon.sourceforge.net/[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
+* Using ObjectModel
+
+The easy one
+
+== Setting a custom XPathFactory using System Property
+
+*Since Camel 2.3*
+
+Camel now supports reading the
+http://java.sun.com/j2se/1.5.0/docs/api/javax/xml/xpath/XPathFactory.html#newInstance(java.lang.String)[JVM
+system property `javax.xml.xpath.XPathFactory`] that can be used to set
+a custom XPathFactory to use.
+
+This unit test shows how this can be done to use Saxon instead:
+
+Camel will log at `INFO` level if it uses a non default XPathFactory
+such as:
+
+[source]
+----
+XPathBuilder  INFO  Using system property javax.xml.xpath.XPathFactory:http://saxon.sf.net/jaxp/xpath/om with value:
+                    net.sf.saxon.xpath.XPathFactoryImpl when creating XPathFactory
+----
+
+To use Apache Xerces you can configure the system property
+
+[source]
+----
+-Djavax.xml.xpath.XPathFactory=org.apache.xpath.jaxp.XPathFactoryImpl
+----
+
+== Enabling Saxon from Spring DSL
+
+*Since Camel 2.10*
+
+Similarly to Java DSL, to enable Saxon from Spring DSL you have three
+options:
+
+Specifying the factory
+
+[source,xml]
+----
+<xpath factoryRef="saxonFactory" resultType="java.lang.String">current-dateTime()</xpath>
+----
+
+Specifying the object model
+
+[source,xml]
+----
+<xpath objectModel="http://saxon.sf.net/jaxp/xpath/om" resultType="java.lang.String">current-dateTime()</xpath>
+----
+
+Shortcut
+
+[source,xml]
+----
+<xpath saxon="true" resultType="java.lang.String">current-dateTime()</xpath>
+----
+
+== Namespace auditing to aid debugging
+
+*Since Camel 2.10*
+
+A large number of XPath-related issues that users frequently face are
+linked to the usage of namespaces. You may have some misalignment
+between the namespaces present in your message and those that your XPath
+expression is aware of or referencing. XPath predicates or expressions
+that are unable to locate the XML elements and attributes due to
+namespaces issues may simply look like "they are not working", when in
+reality all there is to it is a lack of namespace definition.
+
+Namespaces in XML are completely necessary, and while we would love to
+simplify their usage by implementing some magic or voodoo to wire
+namespaces automatically, truth is that any action down this path would
+disagree with the standards and would greatly hinder interoperability.
+
+Therefore, the utmost we can do is assist you in debugging such issues
+by adding two new features to the XPath Expression Language and are thus
+accesible from both predicates and expressions.
+
+#=== Logging the Namespace Context of your XPath expression/predicate
+
+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:
+
+[source]
+----
+[me: {prefix -> namespace}, {prefix -> namespace}], [parent: [me: {prefix -> namespace}, {prefix -> namespace}], [parent: [me: {prefix -> namespace}]]]
+----
+
+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
+xref:xpath-language.adoc[Auditing Namespaces], in which case the logging will
+occur on the INFO level
+
+== 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.
+
+Some points to take into account:
+
+* The implicit XML namespace
+(xmlns:xml="http://www.w3.org/XML/1998/namespace") is suppressed from
+the output because it adds no value
+* Default namespaces are listed under the DEFAULT keyword in the output
+* Keep in mind that namespaces can be remapped under different scopes.
+Think of a top-level 'a' prefix which in inner elements can be assigned
+a different namespace, or the default namespace changing in inner
+scopes. For each discovered prefix, all associated URIs are listed.
+
+You can enable this option in Java DSL and Spring DSL.
+
+Java DSL:
+
+[source,java]
+----
+XPathBuilder.xpath("/foo:person/@id", String.class).logNamespaces()
+----
+
+Spring DSL:
+
+[source,xml]
+----
+<xpath logNamespaces="true" resultType="String">/foo:person/@id</xpath>
+----
+
+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:
+
+[source]
+----
+2012-01-16 13:23:45,878 [stSaxonWithFlag] INFO  XPathBuilder  - Namespaces discovered in message: 
+{xmlns:a=[http://apache.org/camel], DEFAULT=[http://apache.org/default], 
+xmlns:b=[http://apache.org/camelA, http://apache.org/camelB]}
+----
+
+== Loading script from external resource
+
+*Since Camel 2.11*
+
+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"`,
+eg to refer to a file on the classpath you can do:
+
+[source,java]
+----
+.setHeader("myHeader").xpath("resource:classpath:myxpath.txt", String.class)
+----
+
+== Dependencies
+
+The XPath language is part of camel-core.
+
+include::camel-spring-boot::page$xpath-starter.adoc[]
diff --git a/docs/components/modules/languages/pages/xquery-language.adoc b/docs/components/modules/languages/pages/xquery-language.adoc
new file mode 100644
index 0000000..fd41773
--- /dev/null
+++ b/docs/components/modules/languages/pages/xquery-language.adoc
@@ -0,0 +1,159 @@
+[[xquery-language]]
+= XQuery Language
+:page-source: components/camel-saxon/src/main/docs/xquery-language.adoc
+
+*Since Camel 1.0*
+
+Camel supports http://www.w3.org/TR/xquery/[XQuery] to allow an
+Expression or Predicate to be
+used in the DSL or xref:manual::xml-configuration.adoc[Xml
+Configuration]. For example you could use XQuery to create an
+Predicate in a xref:manual:eips:filter-eip.adoc[Message
+Filter] or as an Expression for a
+Recipient List.
+
+== XQuery Language options
+
+// language options: START
+The XQuery language supports 3 options, which are listed below.
+
+
+
+[width="100%",cols="2,1m,1m,6",options="header"]
+|===
+| Name | Default | Java Type | Description
+| type |  | String | Sets the class name of the result type (type from output) The default result type is NodeSet
+| headerName |  | String | Name of header to use as input, instead of the message body
+| trim | true | Boolean | Whether to trim the value to remove leading and trailing whitespaces and line breaks
+|===
+// language options: END
+
+== Examples
+
+[source,java]
+---------------------------
+from("queue:foo")
+  .filter().xquery("//foo")
+  .to("queue:bar")
+---------------------------
+
+You can also use functions inside your query, in which case you need an
+explicit type conversion (or you will get a org.w3c.dom.DOMException:
+HIERARCHY_REQUEST_ERR) by passing the Class as a second argument to the
+*xquery()* method.
+
+[source,java]
+-----------------------------------------------------------------------------
+from("direct:start")
+  .recipientList().xquery("concat('mock:foo.', /person/@city)", String.class);
+-----------------------------------------------------------------------------
+
+== Variables
+
+The IN message body will be set as the `contextItem`. Besides this these
+Variables is also added as parameters:
+
+[width="100%",cols="10%,10%,80%",options="header",]
+|=======================================================================
+|Variable |Type |Description
+
+|exchange |Exchange |The current Exchange
+
+|in.body |Object |The In message's body
+
+|out.body |Object |The OUT message's body (if any)
+
+|in.headers.* |Object |You can access the value of exchange.in.headers with key *foo* by using
+the variable which name is in.headers.foo
+
+|out.headers.* |Object |You can access the value of exchange.out.headers with key *foo* by using
+the variable which name is out.headers.foo variable
+
+|*key name* |Object |Any exchange.properties and exchange.in.headers and any additional
+parameters set using `setParameters(Map)`. These parameters is added
+with they own key name, for instance if there is an IN header with the
+key name *foo* then its added as *foo*.
+|=======================================================================
+
+== Using XML configuration
+
+If you prefer to configure your routes in your Spring
+XML file then you can use XPath expressions as follows
+
+[source,xml]
+---------------------------------------------------------------------------------------------------------------
+<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.xsd
+       http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
+
+  <camelContext id="camel" xmlns="http://activemq.apache.org/camel/schema/spring">
+    <route>
+      <from uri="activemq:MyQueue"/>
+      <filter>
+        <xquery>/foo:person[@name='James']</xquery>
+        <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 XQuery expressions!
+
+When you use functions in your XQuery expression you need an explicit
+type conversion which is done in the xml configuration via the *@type*
+attribute:
+
+[source,xml]
+-------------------------------------------------------------------------------
+    <xquery type="java.lang.String">concat('mock:foo.', /person/@city)</xquery>
+-------------------------------------------------------------------------------
+
+== Learning XQuery
+
+XQuery is a very powerful language for querying, searching, sorting and
+returning XML. For help learning XQuery try these tutorials
+
+* Mike Kay's http://www.stylusstudio.com/xquery_primer.html[XQuery
+Primer]
+* the W3Schools http://www.w3schools.com/xquery/default.asp[XQuery
+Tutorial]
+
+You might also find the http://www.w3.org/TR/xpath-functions/[XQuery
+function reference] useful
+
+== 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"`,
+eg to refer to a file on the classpath you can do:
+
+[source,java]
+------------------------------------------------------------------------------
+.setHeader("myHeader").xquery("resource:classpath:myxquery.txt", String.class)
+------------------------------------------------------------------------------
+
+== Dependencies
+
+To use XQuery in your camel routes you need to add the a dependency on
+*camel-saxon* which implements the XQuery language.
+
+If you use maven you could just add the following to your pom.xml,
+substituting the version number for the latest & greatest release (see
+the download page for the latest versions).
+
+[source,java]
+--------------------------------------
+<dependency>
+  <groupId>org.apache.camel</groupId>
+  <artifactId>camel-saxon</artifactId>
+  <version>x.x.x</version>
+</dependency>
+--------------------------------------
+
+include::camel-spring-boot::page$saxon-starter.adoc[]