| = XSLT Component |
| :doctitle: XSLT |
| :shortname: xslt |
| :artifactid: camel-xslt |
| :description: Transforms XML payload using an XSLT template. |
| :since: 1.3 |
| :supportlevel: Stable |
| :tabs-sync-option: |
| :component-header: Only producer is supported |
| :core: |
| //Manually maintained attributes |
| :camel-spring-boot-name: xslt |
| |
| *Since Camel {since}* |
| |
| *{component-header}* |
| |
| The XSLT component allows you to process a message using an |
| http://www.w3.org/TR/xslt[XSLT] template. This can be ideal when using |
| Templating to generate response for requests. |
| |
| == URI format |
| |
| ---- |
| xslt:templateName[?options] |
| ---- |
| |
| The URI format contains *templateName*, which can be one of the following: |
| |
| * the classpath-local URI of the template to invoke |
| * the complete URL of the remote template. |
| |
| You can append query options to the URI in the following format: |
| |
| *?option=value&option=value&...* |
| |
| .Example URIs |
| [options="header"] |
| |================================================================= |
| |URI |Description |
| |xslt:com/acme/mytransform.xsl|Refers to the file com/acme/mytransform.xsl on the classpath |
| |xslt:file:///foo/bar.xsl |Refers to the file /foo/bar.xsl |
| |xslt:http://acme.com/cheese/foo.xsl|Refers to the remote http resource |
| |================================================================= |
| |
| |
| |
| // component-configure options: START |
| |
| // component-configure options: END |
| |
| // component options: START |
| include::partial$component-configure-options.adoc[] |
| include::partial$component-endpoint-options.adoc[] |
| // component options: END |
| |
| // endpoint options: START |
| |
| // endpoint options: END |
| |
| / component headers: START |
| include::partial$component-endpoint-headers.adoc[] |
| // component headers: END |
| |
| == Using XSLT endpoints |
| |
| The following format is an example of using an XSLT template to formulate a response for a message for InOut |
| message exchanges (where there is a `JMSReplyTo` header) |
| |
| [source,java] |
| ---- |
| from("activemq:My.Queue"). |
| to("xslt:com/acme/mytransform.xsl"); |
| ---- |
| |
| |
| 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 Useable Parameters into the XSLT |
| |
| By default, all headers are added as parameters which are then available in |
| the XSLT. + |
| To make the parameters useable, you will need to declare them. |
| |
| [source,xml] |
| ---- |
| <setHeader name="myParam"><constant>42</constant></setHeader> |
| <to uri="xslt:MyTransform.xsl"/> |
| ---- |
| |
| The parameter also needs to be declared in the top level of the XSLT 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 the following code: |
| |
| [source,xml] |
| ---- |
| <camelContext xmlns="http://activemq.apache.org/camel/schema/spring"> |
| <route> |
| <from uri="activemq:My.Queue"/> |
| <to uri="xslt:org/apache/camel/spring/processor/example.xsl"/> |
| <to uri="activemq:Another.Queue"/> |
| </route> |
| </camelContext> |
| ---- |
| |
| == Using xsl:include |
| |
| Camel provides its own implementation of `URIResolver`. This allows |
| Camel to load included files from the classpath. |
| |
| For example the include file in the following code will be located relative to the starting endpoint. |
| |
| [source,xml] |
| ---- |
| <xsl:include href="staff_template.xsl"/> |
| ---- |
| |
| This means that Camel will locate the file in the *classpath* as |
| *org/apache/camel/component/xslt/staff_template.xsl* + |
| |
| You can use `classpath:` or `file:` to instruct Camel to look either in the classpath or file system. If you omit |
| the prefix then Camel uses the prefix from the endpoint configuration. |
| If no prefix is specified in the endpoint configuration, the default is `classpath:`. |
| |
| You can also refer backwards in the include paths. In the following example, the xsl file will be resolved under `org/apache/camel/component`. |
| |
| [source,xml] |
| ---- |
| <xsl:include href="../staff_other_template.xsl"/> |
| ---- |
| |
| |
| == Using xsl:include and default prefix |
| |
| Camel will use the prefix from the endpoint configuration as the default prefix. |
| |
| You can explicitly specify `file:` or `classpath:` loading. The two loading types can be mixed in a XSLT script, if necessary. |
| |
| == Dynamic stylesheets |
| |
| To provide a dynamic stylesheet at runtime you can either |
| |
| - Define a dynamic URI. See xref:manual:faq:how-to-use-a-dynamic-uri-in-to.adoc[How to use a dynamic URI in |
| to()] for more information. |
| - Use header with the stylesheet. |
| |
| When using a header for dynamic stylesheet, then you can either refer to the stylesheet as a `file` or `classpath` |
| with the header `CamelXsltResourceUri`, such as: |
| |
| [source,java] |
| ---- |
| from("direct:transform") |
| .setHeader("CamelXsltResourceUri", simple("file:styles/${header.region}.xsl")) |
| .to("xslt:template.xsl?allowTemplateFromHeader=true"); |
| ---- |
| |
| Here we set the `CamelXsltResourceUri` header to refer to a stylesheet to be loaded from the file system, |
| with a dynamic name that is computed from another header (`region`). |
| |
| Notice how the `allowTemplateFromHeader` must be set to `true` on the XSLT endpoint to support dynamic templates. |
| |
| You can also use the header `CamelXsltStylesheet` which instead should contain the content of the stylesheet |
| to use, instead of referring to a file as the example from above. |
| |
| TIP: You can set `contentCache=false` and refer to a non-existing template, such as `"xslt:dummy.xsl?contentCache=false&allowTemplateFromHeader=true"` |
| as this will tell Camel to not load `dummy.xsl` on startup but to load the stylesheet on demand. And because you |
| provide the stylesheet via headers then its fully dynamic. |
| |
| == Accessing warnings, errors and fatalErrors from XSLT ErrorListener |
| |
| Any warning/error or fatalError is stored on |
| the current Exchange as a property with the |
| keys `Exchange.XSLT_ERROR`, `Exchange.XSLT_FATAL_ERROR`, |
| or `Exchange.XSLT_WARNING` which allows end users to get hold of any |
| errors happening during transformation. |
| |
| 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,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> |
| ---- |
| |
| The exception is stored on the Exchange as a warning with the |
| key `Exchange.XSLT_WARNING.` |
| |
| |
| |
| include::spring-boot:partial$starter.adoc[] |