Transforming with XSLT

When you want to transform an XML message using XSLT, use Camel's XSLT Component. This is similar to the Transforming inline with XQuery recipe except that there is no XSLT Expression Language, so it can only be used as an endpoint.

This recipe will show you how to transform a message using an external XSLT resource.

Getting ready

The Java code for this recipe is located in the org.camelcookbook.transformation.xslt package. Spring XML files are located under src/main/resources/META-INF/spring and prefixed with xslt.

How to do it...

In a Camel route, add the xslt processor step into the route at the point where you want the XSLT transformation to occur. The XSLT file must be referenced as an external resource, and depending on where the file is located, prefixed with either classpath: (default if not using a prefix), file:, or http:.

In the XML DSL, this is written as:

<route>
  <from uri="direct:start"/>
  <to uri="xslt:book.xslt"/>
</route>

In the Java DSL, the same route is expressed as:

from("direct:start")
  .to("xslt:book.xslt");

The next processing step in the route will see the transformed message content in the body of the exchange.

How it works...

The following example shows how the preceding steps will process an XML file.

Consider the following input XML message:

<bookstore>
  <book category="COOKING">
    <title lang="en">Everyday Italian</title>
    <author>Giada De Laurentiis</author>
    <year>2005</year>
    <price>30.00</price>
  </book>
  <book category="CHILDREN">
    <title lang="en">Harry Potter</title>
    <author>J K. Rowling</author>
    <year>2005</year>
    <price>29.99</price>
  </book>
  <book category="PROGRAMMING">
    <title lang="en">Apache Camel Developer's Cookbook</title>
    <author>Scott Cranton</author>
    <author>Jakub Korab</author>
    <year>2013</year>
    <price>49.99</price>
  </book>
  <book category="WEB">
    <title lang="en">Learning XML</title>
    <author>Erik T. Ray</author>
    <year>2003</year>
    <price>39.95</price>
  </book>
</bookstore>

Process this with the following XSLT contained in books.xslt:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output omit-xml-declaration="yes"/>

  <xsl:template match="/">
    <books>
      <xsl:apply-templates
          select="/bookstore/book/title[../price>30]">
        <xsl:sort select="."/>
      </xsl:apply-templates>
    </books>
  </xsl:template>

  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

The result will appear as follows:

<books>
  <title lang="en">Apache Camel Developer's Cookbook</title>
  <title lang="en">Learning XML</title>
</books>

The Camel XSLT Processor internally runs the message body through a registered Java XML transformer using the XSLT file referenced by the endpoint. This processor uses Camel's Type Converter capabilities to convert the input message body type to one of the supported XML source models in the following order of priority:

  • StAXSource (off by default; this can be enabled by setting allowStAX=true on the endpoint URI)
  • SAXSource
  • StreamSource
  • DOMSource

Camel's Type Converter can convert from most input types (String, File, byte[], and so on) to one of the XML source types for most XML content loaded through other Camel endpoints with no extra work on your part. The output data type for the message is, by default, a String, and is configurable using the output parameter on the xslt endpoint URI.

There's more...

The XSLT Processor passes in headers, properties, and parameters associated with the message. These will show up as XSLT parameters that can be referenced within your XSLT statements.

You can pass in the names of the books as parameters to the XSLT template; to do so, modify the previous XLST as follows:

<xsl:param name="myParamValue"/>

<xsl:template match="/">
  <books>
    <xsl:attribute name="value">
      <xsl:value-of select="$myParamValue"/>
    </xsl:attribute>
    <xsl:apply-templates
        select="/bookstore/book/title[../price>$myParamValue]">
      <xsl:sort select="."/>
    </xsl:apply-templates>
  </books>
</xsl:template>

The Exchange instance will be associated with a parameter called exchange; the IN message with a parameter called in; and the message headers, properties, and parameters will be associated XSLT parameters with the same name. To use these in your XSLT, you need to explicitly declare a parameter of the same name in your XSLT file. In the previous example, it is possible to use either a message header or exchange property called myParamValue.

See also

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.29.105