Repository: camel Updated Branches: refs/heads/master 19fcfa88b -> 2cc685701
http://git-wip-us.apache.org/repos/asf/camel/blob/2cc68570/camel-core/src/main/docs/xpath-language.adoc ---------------------------------------------------------------------- diff --git a/camel-core/src/main/docs/xpath-language.adoc b/camel-core/src/main/docs/xpath-language.adoc index f3cedbf..79a8a42 100644 --- a/camel-core/src/main/docs/xpath-language.adoc +++ b/camel-core/src/main/docs/xpath-language.adoc @@ -22,18 +22,18 @@ link:stream-caching.html[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 @@ -67,7 +67,7 @@ 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 @@ -81,21 +81,21 @@ namespace is `http://camel.apache.org/schema/spring`. |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 +==== 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 +==== 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: @@ -111,7 +111,7 @@ 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. @@ -126,9 +126,9 @@ exchange: link:properties.html[Properties] component (property placeholders). |function:simple |simple expression |Object |*Camel 2.5:* To evaluate a link:simple.html[Simple] expression. -|======================================================================= +|=== -*Notice:* `function:properties` and `function:simple` is not supported +CAUTION: `function:properties` and `function:simple` is not supported when the return type is a `NodeSet`, such as when using with a link:splitter.html[Splitter] EIP. @@ -142,7 +142,7 @@ If you prefer to configure your routes in your link:spring.html[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=" @@ -159,7 +159,7 @@ XML file then you can use XPath expressions as follows </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! @@ -178,25 +178,25 @@ link:xpath.html[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: + *Available as of 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 @@ -209,15 +209,13 @@ type so the concat function works. 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. -In XML DSL: - And in Java DSL you specify the headerName as the 2nd parameter as shown: [source,java] ------------------------------------------------------------- +---- xpath("/invoice/@orderType = 'premium'", "invoiceDetails") ------------------------------------------------------------- +---- === Examples @@ -261,7 +259,7 @@ want will be available for use in your XPath expression. For example [source,java] ----------------------------------------------------------------------------------------------------------- +---- public class Foo { @MessageDriven(uri = "activemq:my.queue") @@ -269,7 +267,7 @@ public class Foo { // process the inbound message here } } ----------------------------------------------------------------------------------------------------------- +---- === Using XPathBuilder without an Exchange @@ -287,9 +285,9 @@ link:camelcontext.html[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. @@ -297,19 +295,19 @@ 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); ------------------------------------------------------------------------------------------------------------------ +---- +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>"); --------------------------------------------------------------------------------------------------- +---- +String name = XPathBuilder.xpath("foo/bar").evaluate(context, "<foo><bar>cheese</bar></foo>"); +---- === Using Saxon with XPathBuilder @@ -321,9 +319,8 @@ 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 +* Using a factory +* Using ObjectModel The easy one @@ -341,18 +338,18 @@ 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,java] --------------------------------------------------------------------------------------------------------------------- +[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,java] ---------------------------------------------------------------------- +[source] +---- -Djavax.xml.xpath.XPathFactory=org.apache.xpath.jaxp.XPathFactoryImpl ---------------------------------------------------------------------- +---- === Enabling Saxon from Spring DSL @@ -364,23 +361,23 @@ 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 @@ -412,10 +409,10 @@ represents Namespace Contexts in a hierarchical fashion (parent-child relationships), the entire tree is output in a recursive manner with the following format: -[source,java] -------------------------------------------------------------------------------------------------------------------------------------------------------- +[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: @@ -426,7 +423,7 @@ logger such as `org.apache.camel` or the root logger link:xpath.html[Auditing Namespaces], in which case the logging will occur on the INFO level -#=== Auditing namespaces +=== Auditing namespaces Camel is able to discover and dump all namespaces present on every incoming message before evaluating an XPath expression, providing all @@ -454,27 +451,27 @@ 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,java] --------------------------------------------------------------------------------------------------- +[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 @@ -486,9 +483,9 @@ such as `"classpath:"`, `"file:"`, or `"http:"`. + eg to refer to a file on the classpath you can do: [source,java] ----------------------------------------------------------------------------- +---- .setHeader("myHeader").xpath("resource:classpath:myxpath.txt", String.class) ----------------------------------------------------------------------------- +---- === Dependencies http://git-wip-us.apache.org/repos/asf/camel/blob/2cc68570/camel-core/src/main/docs/xslt-component.adoc ---------------------------------------------------------------------- diff --git a/camel-core/src/main/docs/xslt-component.adoc b/camel-core/src/main/docs/xslt-component.adoc index c1c309c..17cef01 100644 --- a/camel-core/src/main/docs/xslt-component.adoc +++ b/camel-core/src/main/docs/xslt-component.adoc @@ -8,10 +8,10 @@ link:templating.html[Templating] to generate respopnses for requests. === URI format -[source,java] ---------------------------- +[source] +---- xslt:templateName[?options] ---------------------------- +---- Where *templateName* is the classpath-local URI of the template to invoke; or the complete URL of the remote template. Refer to the @@ -27,24 +27,24 @@ URI Description -[source,java] ------------------------------ +[source] +---- xslt:com/acme/mytransform.xsl ------------------------------ +---- refers to the file com/acme/mytransform.xsl on the classpath -[source,java] ------------------------- +[source] +---- xslt:file:///foo/bar.xsl ------------------------- +---- refers to the file /foo/bar.xsl -[source,java] ------------------------------------ +[source] +---- xslt:http://acme.com/cheese/foo.xsl ------------------------------------ +---- refers to the remote http resource @@ -52,14 +52,14 @@ Maven users will need to add the following dependency to their `pom.xml` for this component when using *Camel 2.8* or older: [source,xml] ------------------------------------------------------------- +---- <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-spring</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency> ------------------------------------------------------------- +---- From Camel 2.9 onwards the link:xslt.html[XSLT] component is provided directly in the camel-core. @@ -135,10 +135,10 @@ with the following path and query parameters: For example you could use something like [source,java] --------------------------------------- +---- from("activemq:My.Queue"). to("xslt:com/acme/mytransform.xsl"); --------------------------------------- +---- To use an XSLT template to formulate a response for a message for InOut message exchanges (where there is a `JMSReplyTo` header). @@ -147,11 +147,11 @@ If you want to use InOnly and consume the message and send it to another destination you could use the following route: [source,java] --------------------------------------- +---- from("activemq:My.Queue"). to("xslt:com/acme/mytransform.xsl"). to("activemq:Another.Queue"); --------------------------------------- +---- === Getting Parameters into the XSLT to work with @@ -161,29 +161,29 @@ the XSLT. + _useable_. [source,xml] -------------------------------------------------------------------- +---- <setHeader headerName="myParam"><constant>42</constant></setHeader> <to uri="xslt:MyTransform.xsl"/> -------------------------------------------------------------------- +---- And the XSLT just needs to declare it at the top level for it to be available: [source,xml] ------------------------------- +---- <xsl: ...... > <xsl:param name="myParam"/> <xsl:template ...> ------------------------------- +---- === Spring XML versions To use the above examples in Spring XML you would use something like [source,xml] ------------------------------------------------------------------------ +---- <camelContext xmlns="http://activemq.apache.org/camel/schema/spring"> <route> <from uri="activemq:My.Queue"/> @@ -191,7 +191,7 @@ To use the above examples in Spring XML you would use something like <to uri="activemq:Another.Queue"/> </route> </camelContext> ------------------------------------------------------------------------ +---- There is a http://svn.apache.org/repos/asf/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/XsltTest.java[test @@ -210,9 +210,9 @@ JVM starting folder. For example this include: [source,xml] ----------------------------------------- +---- <xsl:include href="staff_template.xsl"/> ----------------------------------------- +---- Will lookup the `staff_tempkalte.xsl` file from the starting folder where the application was started. @@ -225,17 +225,17 @@ than before. For example this include: [source,xml] ----------------------------------------- +---- <xsl:include href="staff_template.xsl"/> ----------------------------------------- +---- Will now be located relative from the starting endpoint, which for example could be: [source,java] ----------------------------------------------------------------------- +---- .to("xslt:org/apache/camel/component/xslt/staff_include_relative.xsl") ----------------------------------------------------------------------- +---- Which means Camel will locate the file in the *classpath* as `org/apache/camel/component/xslt/staff_template.xsl`. + @@ -251,20 +251,20 @@ If that neither has one, then classpath is assumed. You can also refer back in the paths such as [source,java] ------------------------------------------------------ +---- <xsl:include href="../staff_other_template.xsl"/> ------------------------------------------------------ +---- Which then will resolve the xsl file under `org/apache/camel/component`. -#=== Using xsl:include and default prefix +=== Using xsl:include and default prefix When using xsl:include such as: [source,xml] ----------------------------------------- +---- <xsl:include href="staff_template.xsl"/> ----------------------------------------- +---- Then in Camel 2.10.3 and older, then Camel will use "classpath:" as the default prefix, and load the resource from the classpath. This works for @@ -272,25 +272,25 @@ most cases, but if you configure the starting resource to load from file, [source,java] ----------------------------------------------------- +---- .to("xslt:file:etc/xslt/staff_include_relative.xsl") ----------------------------------------------------- +---- .. then you would have to prefix all your includes with "file:" as well. [source,xml] ---------------------------------------------- +---- <xsl:include href="file:staff_template.xsl"/> ---------------------------------------------- +---- From Camel 2.10.4 onwards we have made this easier as Camel will use the prefix from the endpoint configuration as the default prefix. So from Camel 2.10.4 onwards you can do: [source,xml] ----------------------------------------- +---- <xsl:include href="staff_template.xsl"/> ----------------------------------------- +---- Which will load the staff_template.xsl resource from the file system, as the endpoint was configured with "file:" as prefix. + @@ -303,14 +303,10 @@ unusual, as most people either use file or classpath based resources. Since Saxon 9.2, writing extension functions has been supplemented by a new mechanism, referred to as http://www.saxonica.com/html/documentation/extensibility/integratedfunctions[integrated -extension functions] you can now easily use camel: - - - -- Java example: +extension functions] you can now easily use camel as shown in the below example: [source,java] ---------------------------------------------------------------------------------------------------------------------------------- +---- SimpleRegistry registry = new SimpleRegistry(); registry.put("function1", new MyExtensionFunction1()); registry.put("function2", new MyExtensionFunction2()); @@ -323,30 +319,25 @@ context.addRoutes(new RouteBuilder() { .to("xslt:org/apache/camel/component/xslt/extensions/extensions.xslt?saxonExtensionFunctions=#function1,#function2"); } }); ---------------------------------------------------------------------------------------------------------------------------------- +---- - -Spring example: +And with Spring XML: [source,xml] ------------------------------------------------------------------------------------------------------------------------------ +---- +<bean id="function1" class="org.apache.camel.component.xslt.extensions.MyExtensionFunction1"/> +<bean id="function2" class="org.apache.camel.component.xslt.extensions.MyExtensionFunction2"/> + <camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:extensions"/> <to uri="xslt:org/apache/camel/component/xslt/extensions/extensions.xslt?saxonExtensionFunctions=#function1,#function2"/> </route> </camelContext> +---- -<bean id="function1" class="org.apache.camel.component.xslt.extensions.MyExtensionFunction1"/> -<bean id="function2" class="org.apache.camel.component.xslt.extensions.MyExtensionFunction2"/> ------------------------------------------------------------------------------------------------------------------------------ - - - - - === Dynamic stylesheets To provide a dynamic stylesheet at runtime you can define a dynamic URI. @@ -372,22 +363,22 @@ For example in the stylesheet below, we want to terminate if a staff has an empty dob field. And to include a custom error message using xsl:message. -[source,java] ---------------------------------------------------------------------------------------- - <xsl:template match="/"> - <html> - <body> - <xsl:for-each select="staff/programmer"> - <p>Name: <xsl:value-of select="name"/><br /> - <xsl:if test="dob=''"> - <xsl:message terminate="yes">Error: DOB is an empty string!</xsl:message> - </xsl:if> - </p> - </xsl:for-each> - </body> - </html> - </xsl:template> ---------------------------------------------------------------------------------------- +[source,xml] +---- +<xsl:template match="/"> + <html> + <body> + <xsl:for-each select="staff/programmer"> + <p>Name: <xsl:value-of select="name"/><br /> + <xsl:if test="dob=''"> + <xsl:message terminate="yes">Error: DOB is an empty string!</xsl:message> + </xsl:if> + </p> + </xsl:for-each> + </body> + </html> +</xsl:template> +---- This information is not available on the Exchange stored as an Exception that contains the message in the `getMessage()` method on the exception. @@ -399,7 +390,6 @@ key `Exchange.XSLT_WARNING.` Here are some observations from Sameer, a Camel user, which he kindly shared with us: -________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ In case anybody faces issues with the XSLT endpoint please review these points. @@ -416,11 +406,11 @@ After a few hours of cranking my mind, I had to do the following to get it to work (thanks to some posts on the users forum that gave some clue): -\1. Use the transformerFactory option in the route +1. Use the transformerFactory option in the route `("xslt:my-transformer.xsl?transformerFactory=tFactory")` with the `tFactory` bean having bean defined in the spring context for `class="org.apache.xalan.xsltc.trax.TransformerFactoryImpl"`. + - 2. Added the Xalan jar into my maven pom. +2. Added the Xalan jar into my maven pom. My guess is that the default xml parsing mechanism supplied within the JDK (I am using 1.6.0_03) does not work right in this context and does @@ -433,7 +423,6 @@ One workaround is to add the 2.1 jar to the `jre/lib/endorsed` directory for the jvm or as specified by the container. Hope this post saves newbie Camel riders some time. -________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ === See Also http://git-wip-us.apache.org/repos/asf/camel/blob/2cc68570/camel-core/src/main/docs/zip-dataformat.adoc ---------------------------------------------------------------------- diff --git a/camel-core/src/main/docs/zip-dataformat.adoc b/camel-core/src/main/docs/zip-dataformat.adoc index 67b7c19..276ca6e 100644 --- a/camel-core/src/main/docs/zip-dataformat.adoc +++ b/camel-core/src/main/docs/zip-dataformat.adoc @@ -38,17 +38,17 @@ payload employing zip compression `Deflater.BEST_COMPRESSION` and send it an ActiveMQ queue called MY_QUEUE. [source,java] --------------------------------------------------------------------------------------------- +---- from("direct:start").marshal().zip(Deflater.BEST_COMPRESSION).to("activemq:queue:MY_QUEUE"); --------------------------------------------------------------------------------------------- +---- Alternatively if you would like to use the default setting you could send it as [source,java] -------------------------------------------------------------------- +---- from("direct:start").marshal().zip().to("activemq:queue:MY_QUEUE"); -------------------------------------------------------------------- +---- === Unmarshal @@ -59,9 +59,9 @@ during the marshalling should be identical to the one employed during unmarshalling to avoid errors. [source,java] -------------------------------------------------------------------------------------------- +---- from("activemq:queue:MY_QUEUE").unmarshal().zip().process(new UnZippedMessageProcessor()); -------------------------------------------------------------------------------------------- +---- === Dependencies