blob: d54457e56591f24d1cf69b4e5053781a1b6401f7 [file] [log] [blame]
= 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[]