[[xml-transformation]]
= Transforming XML Payloads

This section covers how to transform XML payloads

[[xml-transformation-beans]]
== Configuring Transformers as Beans

This section will explain the workings of the following transformers and how to configure them as beans:

* link:#xml-unmarshalling-transformer[UnmarshallingTransformer]
* link:#xml-marshalling-transformer[MarshallingTransformer]
* link:#xml-xslt-payload-transformers[XsltPayloadTransformer]

All the XML transformers extend either https://docs.spring.io/spring-integration/api/org/springframework/integration/transformer/AbstractTransformer.html[`AbstractTransformer`] or  https://docs.spring.io/spring-integration/api/org/springframework/integration/transformer/AbstractPayloadTransformer.html[`AbstractPayloadTransformer`] and therefore implement  https://docs.spring.io/spring-integration/api/org/springframework/integration/transformer/Transformer.html[`Transformer`].
When configuring XML transformers as beans in Spring Integration, you would normally configure the `Transformer` in conjunction with a  https://docs.spring.io/spring-integration/api/org/springframework/integration/transformer/MessageTransformingHandler.html[`MessageTransformingHandler`].
This lets the transformer be used as an endpoint.
Finally, we discuss the namespace support, which allows for configuring the transformers as elements in XML.

[[xml-unmarshalling-transformer]]
=== UnmarshallingTransformer

An https://docs.spring.io/spring-integration/api/org/springframework/integration/xml/transformer/UnmarshallingTransformer.html[`UnmarshallingTransformer`] lets an XML `Source` be unmarshalled by using implementations of the https://docs.spring.io/spring/docs/current/spring-framework-reference/html/oxm.html[Spring OXM] `Unmarshaller`.
Spring's Object/XML Mapping support provides several implementations that support marshalling and unmarshalling by using https://en.wikipedia.org/wiki/Java_Architecture_for_XML_Binding[JAXB], https://castor-data-binding.github.io/castor/reference-guide/reference/xml/xml-framework.html[Castor], https://en.wikipedia.org/wiki/JiBX[JiBX], and others.
The unmarshaller requires an instance of `Source`.
If the message payload is not an instance of `Source`, conversion is still attempted.
Currently, `String`, `File`, `byte[]` and `org.w3c.dom.Document` payloads are supported.
To create a custom conversion to a `Source`, you can inject an implementation of a https://docs.spring.io/spring-integration/api/org/springframework/integration/xml/source/SourceFactory.html[`SourceFactory`].

NOTE: If you do not explicitly set a `SourceFactory`, the property on the `UnmarshallingTransformer` is, by default, set to a https://docs.spring.io/spring-integration/api/org/springframework/integration/xml/source/DomSourceFactory.html[`DomSourceFactory`].

Starting with version 5.0, the `UnmarshallingTransformer` also supports an `org.springframework.ws.mime.MimeMessage` as the incoming payload.
This can be useful when we receive a raw `WebServiceMessage` with MTOM attachments over SOAP .
See xref:ws.adoc#mtom-support[MTOM Support] for more information.

The following example shows how to define an unmarshalling transformer:

[source,xml]
----
<bean id="unmarshallingTransformer" class="o.s.i.xml.transformer.UnmarshallingTransformer">
    <constructor-arg>
        <bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
            <property name="contextPath" value="org.example" />
        </bean>
    </constructor-arg>
</bean>
----

[[xml-marshalling-transformer]]
=== Using `MarshallingTransformer`

The https://docs.spring.io/spring-integration/api/org/springframework/integration/xml/transformer/MarshallingTransformer.html[`MarshallingTransformer`] lets an object graph be converted into XML by using a Spring OXM `Marshaller`.
By default, the `MarshallingTransformer` returns a `DomResult`.
However, you can control the type of result by configuring an alternative `ResultFactory`, such as `StringResultFactory`.
In many cases, it is more convenient to transform the payload into an alternative XML format.
To do so, configure a `ResultTransformer`.
Spring integration provides two implementations, one that converts to `String` and another that converts to `Document`.
The following example configures a marshalling transformer that transforms to a document:

[source,xml]
----
<bean id="marshallingTransformer" class="o.s.i.xml.transformer.MarshallingTransformer">
    <constructor-arg>
        <bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
            <property name="contextPath" value="org.example"/>
        </bean>
    </constructor-arg>
    <constructor-arg>
        <bean class="o.s.i.xml.transformer.ResultToDocumentTransformer"/>
    </constructor-arg>
</bean>
----

By default, the `MarshallingTransformer` passes the payload object to the `Marshaller`.
However, if its boolean `extractPayload` property is set to `false`, the entire `Message` instance is passed to the `Marshaller` instead.
That may be useful for certain custom implementations of the `Marshaller` interface, but, typically, the payload is the appropriate source object for marshalling when you delegate to any of the various `Marshaller` implementations.

[[xml-xslt-payload-transformers]]
=== XsltPayloadTransformer

The https://docs.spring.io/spring-integration/api/org/springframework/integration/xml/transformer/XsltPayloadTransformer.html[`XsltPayloadTransformer`] transforms XML payloads by using https://en.wikipedia.org/wiki/XSL_Transformations[Extensible Stylesheet Language Transformations] (XSLT).
The transformer's constructor requires an instance of either https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/io/Resource.html[Resource] or https://docs.oracle.com/javase/6/docs/api/javax/xml/transform/Templates.html[Templates] to be passed in.
Passing in a `Templates` instance allows for greater configuration of the `TransformerFactory` used to create the template instance.

As with the link:#xml-unmarshalling-transformer[`UnmarshallingTransformer`], the `XsltPayloadTransformer` does the actual XSLT transformation against instances of `Source`.
Therefore, if the message payload is not an instance of `Source`, conversion is still attempted.
`String` and `Document` payloads are supported directly.

To create a custom conversion to a `Source`, you can inject an implementation of a https://docs.spring.io/spring-integration/api/org/springframework/integration/xml/source/SourceFactory.html[`SourceFactory`].

NOTE: If a `SourceFactory` is not set explicitly, the property on the `XsltPayloadTransformer` is, by default, set to a  https://docs.spring.io/spring-integration/api/org/springframework/integration/xml/source/DomSourceFactory.html[`DomSourceFactory`].

By default, the `XsltPayloadTransformer` creates a message with a https://docs.oracle.com/javase/6/docs/api/javax/xml/transform/Result.html[`Result`] payload, similar to the `XmlPayloadMarshallingTransformer`.
You can customize this by providing a https://docs.spring.io/spring-integration/api/org/springframework/integration/xml/result/ResultFactory.html[`ResultFactory`] or a  https://docs.spring.io/spring-integration/api/org/springframework/integration/xml/transformer/ResultTransformer.html[`ResultTransformer`].

The following example configures a bean that works as an XSLT payload transformer:

[source,xml]
----
<bean id="xsltPayloadTransformer" class="o.s.i.xml.transformer.XsltPayloadTransformer">
  <constructor-arg value="classpath:org/example/xsl/transform.xsl"/>
  <constructor-arg>
    <bean class="o.s.i.xml.transformer.ResultToDocumentTransformer"/>
  </constructor-arg>
</bean>
----

Starting with Spring Integration 3.0, you can specify the transformer factory class name by using a constructor argument.
You can do so by using the `transformer-factory-class` attribute when you use the namespace.

[[xml-using-result-transformers]]
=== Using `ResultTransformer` Implementations

Both the `MarshallingTransformer` and the `XsltPayloadTransformer` let you specify a https://docs.spring.io/spring-integration/api/org/springframework/integration/xml/transformer/ResultTransformer.html[`ResultTransformer`].
Thus, if the marshalling or XSLT transformation returns a https://docs.oracle.com/javase/6/docs/api/javax/xml/transform/Result.html[`Result`], you have the option to also use a `ResultTransformer` to transform the `Result` into another format.
Spring Integration provides two concrete `ResultTransformer` implementations:

* https://docs.spring.io/spring-integration/api/org/springframework/integration/xml/transformer/ResultToDocumentTransformer.html[`ResultToDocumentTransformer`]
* https://docs.spring.io/spring-integration/api/org/springframework/integration/xml/transformer/ResultToStringTransformer.html[`ResultToStringTransformer`]

By default, the `MarshallingTransformer` always returns a https://docs.oracle.com/javase/6/docs/api/javax/xml/transform/Result.html[`Result`].
By specifying a `ResultTransformer`, you can customize the type of payload returned.

The behavior is slightly more complex for the `XsltPayloadTransformer`.
By default, if the input payload is an instance of `String` or https://docs.oracle.com/javase/6/docs/api/org/w3c/dom/Document.html[`Document`] the `resultTransformer` property is ignored.

However, if the input payload is a https://docs.oracle.com/javase/6/docs/api/javax/xml/transform/Source.html[`Source`] or any other type, the `resultTransformer` property is applied.
Additionally, you can set the `alwaysUseResultFactory` property to `true`, which also causes the specified `resultTransformer` to be used.

For more information and examples, see xref:xml/transformation.adoc#xml-using-result-transformers-namespace[Namespace Configuration and Result Transformers].

[[xml-transformer-namespace]]
== Namespace Support for XML Transformers

Namespace support for all XML transformers is provided in the Spring Integration XML namespace, a template for which was xref:xpath-namespace-support[shown earlier].
The namespace support for transformers creates an instance of either `EventDrivenConsumer` or `PollingConsumer`, according to the type of the provided input channel.
The namespace support is designed to reduce the amount of XML configuration by allowing the creation of an endpoint and transformer that use one element.

[[using-an-unmarshallingtransformer]]
=== Using an `UnmarshallingTransformer`

The namespace support for the `UnmarshallingTransformer` is shown below.
Since the namespace create an endpoint instance rather than a transformer, you can nest a poller within the element to control the polling of the input channel.
The following example shows how to do so:

[source,xml]
----
<int-xml:unmarshalling-transformer id="defaultUnmarshaller"
    input-channel="input" output-channel="output"
    unmarshaller="unmarshaller"/>

<int-xml:unmarshalling-transformer id="unmarshallerWithPoller"
    input-channel="input" output-channel="output"
    unmarshaller="unmarshaller">
    <int:poller fixed-rate="2000"/>
<int-xml:unmarshalling-transformer/>
----

[[using-a-marshallingtransformer]]
=== Using a `MarshallingTransformer`

The namespace support for the marshalling transformer requires an `input-channel`, an `output-channel`, and a reference to a `marshaller`.
You can use the optional `result-type` attribute to control the type of result created.
Valid values are `StringResult` or `DomResult` (the default).
The following example configures a marshalling transformer:

[source,xml]
----
<int-xml:marshalling-transformer
     input-channel="marshallingTransformerStringResultFactory"
     output-channel="output"
     marshaller="marshaller"
     result-type="StringResult" />

<int-xml:marshalling-transformer
    input-channel="marshallingTransformerWithResultTransformer"
    output-channel="output"
    marshaller="marshaller"
    result-transformer="resultTransformer" />

<bean id="resultTransformer" class="o.s.i.xml.transformer.ResultToStringTransformer"/>
----

Where the provided result types do not suffice, you can provide a reference to a custom implementation of `ResultFactory` as an alternative to setting the `result-type` attribute by using the `result-factory` attribute.
The `result-type` and `result-factory` attributes  are mutually exclusive.

NOTE: Internally, the `StringResult` and `DomResult` result types are represented by the `ResultFactory` implementations: https://docs.spring.io/spring-integration/api/org/springframework/integration/xml/result/StringResultFactory.html[`StringResultFactory`] and  https://docs.spring.io/spring-integration/api/org/springframework/integration/xml/result/DomResultFactory.html[`DomResultFactory`] respectively.

[[using-an-xsltpayloadtransformer]]
=== Using an `XsltPayloadTransformer`

Namespace support for the `XsltPayloadTransformer` lets you  either pass in a `Resource` (in order to create the https://docs.oracle.com/javase/6/docs/api/javax/xml/transform/Templates.html[`Templates`] instance) or  pass in a pre-created `Templates` instance as a reference.
As with the marshalling transformer, you can control the type of the result output by specifying either the `result-factory` or the `result-type` attribute.
When you need to convert result before sending, you can use a `result-transformer` attribute to reference an implementation of `ResultTransformer`.

IMPORTANT: If you specify the `result-factory` or the `result-type` attribute, the `alwaysUseResultFactory` property on the underlying https://docs.spring.io/spring-integration/api/org/springframework/integration/xml/transformer/XsltPayloadTransformer.html[`XsltPayloadTransformer`] is set to `true` by the https://docs.spring.io/spring-integration/api/org/springframework/integration/xml/config/XsltPayloadTransformerParser.html[`XsltPayloadTransformerParser`].

The following example configures two XSLT transformers:

[source,xml]
----
<int-xml:xslt-transformer id="xsltTransformerWithResource"
    input-channel="withResourceIn" output-channel="output"
    xsl-resource="org/springframework/integration/xml/config/test.xsl"/>

<int-xml:xslt-transformer id="xsltTransformerWithTemplatesAndResultTransformer"
    input-channel="withTemplatesAndResultTransformerIn" output-channel="output"
    xsl-templates="templates"
    result-transformer="resultTransformer"/>
----

You may need to have access to `Message` data, such as the `Message` headers, in order to assist with transformation.
For example, you may need to get access to certain `Message` headers and pass them on as parameters to a transformer (for example, `transformer.setParameter(..)`).
Spring Integration provides two convenient ways to accomplish this, as the following example shows:

[source,xml]
----
<int-xml:xslt-transformer id="paramHeadersCombo"
    input-channel="paramHeadersComboChannel" output-channel="output"
    xsl-resource="classpath:transformer.xslt"
    xslt-param-headers="testP*, *foo, bar, baz">

    <int-xml:xslt-param name="helloParameter" value="hello"/>
    <int-xml:xslt-param name="firstName" expression="headers.fname"/>
</int-xml:xslt-transformer>
----

If message header names match one-to-one to parameter names, you can use the `xslt-param-headers` attribute.
In it, you can use wildcards for simple pattern matching.
It supports the following simple pattern styles: `xxx*`, `*xxx`, `*xxx*`, and `xxx*yyy`.

You can also configure individual XSLT parameters by using the `<xslt-param/>` element.
On that element, you can set the `expression` attribute or the `value` attribute.
The `expression` attribute should be any valid SpEL expression with the `Message` being the root object of the expression evaluation context.
The `value` attribute (as with any `value` in Spring beans) lets you specify simple scalar values.
You can also use property placeholders (such as `${some.value}`).
So, with the `expression` and `value` attributes, you can map XSLT parameters to any accessible part of the `Message` as well as any literal value.

Starting with Spring Integration 3.0, you can now specify the transformer factory class name by setting the `transformer-factory-class` attribute.

[[xml-using-result-transformers-namespace]]
== Namespace Configuration and Result Transformers

We cover using result transformers in xref:xml/transformation.adoc#xml-using-result-transformers[Using `ResultTransformer` Implementations].
The examples in this section use XML namespace configuration to illustrates several special use cases.
First, we define the `ResultTransformer`, as the following example shows:

[source,xml]
----
<beans:bean id="resultToDoc" class="o.s.i.xml.transformer.ResultToDocumentTransformer"/>
----

This `ResultTransformer` accepts either a `StringResult` or a `DOMResult` as input and converts the input into a `Document`.

Now we can declare the transformer, as follows:

[source,xml]
----
<int-xml:xslt-transformer input-channel="in" output-channel="fahrenheitChannel"
    xsl-resource="classpath:noop.xslt" result-transformer="resultToDoc"/>
----

If the incoming message's payload is of type `Source`, then, as a first step, the `Result` is determined by using the `ResultFactory`.
As we did not specify a `ResultFactory`, the default `DomResultFactory` is used, meaning that the transformation yields a `DomResult`.

However, as we specified a `ResultTransformer`, it is used and the resulting `Message` payload is of type `Document`.

IMPORTANT: The specified `ResultTransformer` is ignored with `String` or `Document` payloads.
If the incoming message's payload is of type `String`, the payload after the XSLT transformation is a `String`.
Similarly, if the incoming message's payload is of type `Document`, the payload after the XSLT transformation is a`Document`.

If the message payload is not a `Source`, a `String`, or a `Document`, as a fallback option, we try to create a`Source` by using the default  https://docs.spring.io/spring-integration/api/org/springframework/integration/xml/source/SourceFactory.html[`SourceFactory`].
As we did not specify a `SourceFactory` explicitly by using the `source-factory` attribute, the default  https://docs.spring.io/spring-integration/api/org/springframework/integration/xml/source/DomSourceFactory.html[`DomSourceFactory`] is used.
If successful, the XSLT transformation is executed as if the payload was of type `Source`, as described in the previous paragraphs.

NOTE: The `DomSourceFactory` supports the creation of a `DOMSource` from a `Document`, a `File`, or a `String` payload.

The next transformer declaration adds a `result-type` attribute that uses `StringResult` as its value.
The `result-type` is internally represented by the `StringResultFactory`.
Thus, you could have also added a reference to a `StringResultFactory`, by using the `result-factory` attribute, which would have been the same.
The following example shows that transformer declaration:

[source,xml]
----
<int-xml:xslt-transformer input-channel="in" output-channel="fahrenheitChannel"
		xsl-resource="classpath:noop.xslt" result-transformer="resultToDoc"
		result-type="StringResult"/>
----

Because we use a `ResultFactory`, the `alwaysUseResultFactory` property of the `XsltPayloadTransformer` class is implicitly set to `true`.
Consequently, the referenced `ResultToDocumentTransformer` is used.

Therefore, if you transform a payload of type `String`, the resulting payload is of type https://docs.oracle.com/javase/6/docs/api/org/w3c/dom/Document.html[`Document`].

[[xsltpayloadtransformer-and-<xsl:output-method=-text-/>]]
=== `XsltPayloadTransformer` and `<xsl:output method="text"/>`

`<xsl:output method="text"/>` tells the XSLT template to produce only text content from the input source.
In this particular case, we have no reason to use a `DomResult`.
Therefore, the https://docs.spring.io/spring-integration/api/org/springframework/integration/xml/transformer/XsltPayloadTransformer.html[`XsltPayloadTransformer`] defaults to `StringResult` if the https://docs.oracle.com/javase/7/docs/api/javax/xml/transform/Transformer.html#getOutputProperties()[output property] called `method` of the underlying `javax.xml.transform.Transformer` returns `text`.
This coercion is performed independently from the inbound payload type.
This behavior is available only you set the if the `result-type` attribute or the `result-factory` attribute for the `<int-xml:xslt-transformer>` component.

