Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 26 Current »

The primary goals of this example are to introduce you to the following:

  1. Transformer written in XSLT with namespaces.
  2. The Smooks configuration file.
  3. Executing the Smooks Transformation.

 
SVN - Download - Other Tutorials

Other Relevant Info:

 
To Build: "mvn clean install"
To Run: "mvn exec:java"

Transforming xml with namespaces

In this example we build a very simple fragment transformer in XSLT. The point of this tutorial is purely to demonstrate how transforming xml with namespaces with Smooks. The use case for this example of transforming between two xml formats that use different namespace. This is a typical use case when one has a canonical data model.

So here's the source xml that is to be transformed:

<Order xmlns="http://milyn.codehaus.org/Smooks" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <header>
        <order-id>1</order-id>
        <status-code>0</status-code>
        <net-amount>59.97</net-amount>
        <total-amount>64.92</total-amount>
        <tax>4.95</tax>
        <date>Wed Nov 15 13:45:28 EST 2006</date>
    </header>
    <customer-details>
        <username>user1</username>
        <name>
            <firstname>Harry</firstname>
            <lastname>Fletcher</lastname>
        </name>
        <state>South Dakota</state>
    </customer-details>
    <order-item>
        <position>1</position>
        <quantity>1</quantity>
        <product-id>364</product-id>
        <title>The 40-Year-Old Virgin</title>
        <price>29.98</price>
    </order-item>
</Order>

And this is the expected result of our transformation:

<CanonicalOrderFormat *xmlns="http://canonical.codehaus.org/Order"*>
    <orderId>1</orderId>
    <item>
        <productId>364</productId>
        <title>The 40-Year-Old Virgin</title>
        <price>29.98</price>
    </item>
</CanonicalOrderFormat>

Notice that CanonicalOrderFormat has a different namepace and only contains a subset of the date from the Order xml instance. 

The Smooks Configuration

In order to apply this transformer to a message fragment, a Smooks Configuration needs to be created. This configuration will target the transformer at a particular message fragment. For more information on configuring XSLT resources, see XslContentDeliveryUnitCreator.

Here's the configuration ("smooks-config.xml"):

<?xml version="1.0"?>
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd"
                      xmlns:xsl="http://www.milyn.org/xsd/smooks/xsl-1.1.xsd">

    <xsl:xsl applyOnElement="$document">
        <xsl:template>
            <![CDATA[
            <xsl:stylesheet
                    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
                    xmlns:xhtml="http://www.w3.org/1999/xhtml"
                    exclude-result-prefixes="smk xhtml"
                    xmlns:smk="http://milyn.codehaus.org/Smooks">

                <xsl:output method="xml" encoding="UTF-8"/>

                <xsl:template match="/">
                    <CanonicalOrderFormat xmlns="http://canonical.codehaus.org/Order">
                        <orderId>
                            <xsl:value-of select="./smk:Order/smk:header/smk:order-id"/>
                        </orderId>
                        <item>
                            <productId>
                                <xsl:value-of select="./smk:Order/smk:order-item/smk:product-id"/>
                            </productId>
                            <title>
                                <xsl:value-of select="./smk:Order/smk:order-item/smk:title"/>
                            </title>
                            <price>
                                <xsl:value-of select="./smk:Order/smk:order-item/smk:price"/>
                            </price>
                        </item>
                    </CanonicalOrderFormat>
                </xsl:template>
            </xsl:stylesheet>
            ]]>
        </xsl:template>
    </xsl:xsl>

</smooks-resource-list>

The resource-config tells Smooks to apply the transformation that is declared "inline" in the  resource element on all <Order>. Notice that we are declaring namespace "http://milyn.codehaus.org/Smooks" with prefix "smk". This namespace is then used in the select expressions to extract the values from the Order xml instance.

Also not the usage of exclude-result-prefixes which specifies that we wish to exclude the specified namespaces from the resulting xml. If this is not declared then then namespace for the prefix will added to the resulting xml, which is not something you want when you are trying to decouple. 

Executing The Transformation

Again, it's exactly the same as with the java-basic tutorial:

// Instantiate Smooks with the config...
Smooks smooks = new Smooks("smooks-config.xml");

// Filter the input message to the outputWriter...
smooks.filter(new StreamSource(messageInStream), new StreamResult(messageOutStream));

Of course, you'd typically cache the Smooks instance.

See the example/Main.java in the example source.

  • No labels