Nav
You are viewing an older version of this section. Click here to navigate to the latest version.

XQuery Transformer

The XQuery Module gives users the ability to perform XQuery transformations on XML messages in Mule. This works in a very similar way to the XSLT Transformer shipped with Mule.

Supported XQuery Versions

Mule 3.6.0 and later versions include XQuery 3.0 support for the XQuery transformer. The transformer’s behavior and syntax remain unaltered from previous versions, and you can declare the version to use in the XQuery script itself (see below).

If you convert to Mule 3.6 and later, more information on XML can be found in XPath3 guide.

For examples on using the XQuery transformer, including the use of features and improvements in version 3.0, see XQuery Support.

Configuration

To use the XQuery transformer you need to add it to your Mule XML configuration.


         
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<mxml:xquery-transformer name="xquery">
        <mxml:xquery-text>
           <![CDATA[
                declare variable $document external;
                declare variable $title external;
                declare variable $rating external;
 
                <cd-listings title='{$title}' rating='{$rating}'> {
                    for $cd in $document/catalog/cd
                    return <cd-title>{data($cd/title)}</cd-title>
                } </cd-listings>
            ]]>
        </mxml:xquery-text>
         
        <mxml:context-property key="title" value="#[header:ListingTitle]"/>
        <mxml:context-property key="rating" value="#[header:ListingRating]"/>
 
    </mxml:xquery-transformer>

Here we are configuring a transformer using in-line XQuery expressions.

We also define two <context-property> elements:


         
      
1
2
<mxml:context-property key="title" value="#[header:ListingTitle]"/>
<mxml:context-property key="rating" value="#[header:ListingRating]"/>

These properties are pulled from the current message and made available in the XQuery context so that they can be referenced in your XQuery statements. These can be object references or you can use Mule Expressions to get information from the current message.

Declaring the XQuery Version

If the XQuery version is not declared, the transformer defaults to version 1.0. Version 3.0 is backwards-compatible and per the spec, all queries in 1.0 are valid in 3.0 and must return the same result.

To select the XQuery version to use, you can include it in the XQuery script, as shown below:


         
      
1
2
3
4
5
...
<mxml:xquerytext>
<![CDATA[
  xquery version "3.0";
...

Configuration Options

Xquery transformerAn Xml transformer uses XQuery to transform the message payload. Transformation objects are pooled for better performance. You can set transformation context properties on the transformer and can pull these properties from the message using Expression Evaluators.

Attributes of <xquery-transformer…​>

Name Type Required Default Description

outputEncoding

string

no

The encoding to use for the resulting XML/Text.

acceptExternalEntities

boolean

no

false

Whether to accept XML documents with references to external files. Default value is false. Setting this value to true will make your application vulnerable to XXE attacks. Use with extreme care.

maxIdleTransformers

integer

no

Transformers are pooled for better throughput, since performing and XQuery transformation can be expensive. This attribute controls how many instances will remain idle in the transformer pool.

maxActiveTransformers

integer

no

The total number of XQuery transformers that will get pooled at any given time.

xquery-file

string

no

The full path to the XQuery template file to use when performing the transformation. This can be a path on the local file system or on the classpath. This attribute is not required if the <xquery-text> element has been set.

configuration-ref

string

no

A reference to a Saxon configuration object to configure the transformer (configured as a Spring bean). If not set, the default Saxon configuration is used.

Child Elements of <xquery-transformer…​>

Name Cardinality Description

context-property

0..*

A property that willbe made available to the XQuery transform context. Expression Evaluators can be used to grab these properties from the message at runtime.

xquery-text

0..1

The inline XQuery script definition. This is not required if the <xquery-file> attribute is set.

Example

Now your configured XQuery transformer can be referenced by an endpoint. In the following example, you can drop and XML file into a directory on the local machine (see the inbound file endpoint) and the result will be written to System.out.

The test data looks like this:


         
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<catalog>
    <cd>
        <title>Empire Burlesque</title>
        <artist>Bob Dylan</artist>
        <country>USA</country>
        <company>Columbia</company>
        <price>10.90</price>
        <year>1985</year>
    </cd>
    <cd>
        <title>Hide your heart</title>
        <artist>Bonnie Tyler</artist>
        <country>UK</country>
        <company>CBS Records</company>
        <price>9.90</price>
        <year>1988</year>
    </cd>
     ...
</catalog>

The result written to System.out will look like this:


         
      
1
2
3
4
5
<cd-listings title="MyList" rating="6">
    <cd-title>Empire Burlesque</cd-title>
    <cd-title>Hide your heart</cd-title>
     ...
</cd-listings>

The full configuration for this examples looks like this:


         
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<mule xmlns="http://www.mulesoft.org/schema/mule/core"
      xmlns:mxml="http://www.mulesoft.org/schema/mule/xml"
      xmlns:vm="http://www.mulesoft.org/schema/mule/vm"
      xmlns:stdio="http://www.mulesoft.org/schema/mule/stdio"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="
      http://www.mulesoft.org/schema/mule/stdio http://www.mulesoft.org/schema/mule/stdio/3.6/mule-stdio.xsd
      http://www.mulesoft.org/schema/mule/vm http://www.mulesoft.org/schema/mule/vm/3.6/mule-vm.xsd
      http://www.mulesoft.org/schema/mule/xml http://www.mulesoft.org/schema/mule/xml/3.6/mule-xml.xsd
       http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/3.6/mule.xsd">
 
    <mxml:xquery-transformer name="xquery">
        <mxml:xquery-text>
           <![CDATA[
                declare variable $document external;
                declare variable $title external;
                declare variable $rating external;
 
                <cd-listings title='{$title}' rating='{$rating}'> {
                    for $cd in $document/catalog/cd
                    return <cd-title>{data($cd/title)}</cd-title>
                } </cd-listings>
            ]]>
        </mxml:xquery-text>
         
        <mxml:context-property key="title" value="#[header:ListingTitle]"/>
        <mxml:context-property key="rating" value="#[header:ListingRating]"/>
 
    </mxml:xquery-transformer>
 
    <flow name="testingFlow1" doc:name="testingFlow1">
        <vm:inbound-endpoint exchange-pattern="one-way" path="test.in" transformer-refs="xquery"/>
        <echo-component/>
        <all>
            <processor-chain>
                <vm:outbound-endpoint exchange-pattern="one-way"/>
            </processor-chain>
            <processor-chain>
                <outbound-endpoint doc:name="Generic"/>
            </processor-chain>
        </all>
    </flow>
</mule>

Testing

This can be tested using the following functional test.


          
       
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class XQueryFunctionalTestCase extends FunctionalTestCase
{
    protected String getConfigResources()
    {
        //Our Mule configuration file
        return "org/mule/test/integration/xml/xquery-functional-test.xml";
    }
 
    public void testMessageTransform() throws Exception
    {
        //We're using Xml Unit to compare results
        //Ignore whitespace and comments
        XMLUnit.setIgnoreWhitespace(true);
        XMLUnit.setIgnoreComments(true);
 
        //Read in src and result data
        String srcData = IOUtils.getResourceAsString("cd-catalog.xml", getClass());
        String resultData = IOUtils.getResourceAsString("cd-catalog-result-with-params.xml", getClass());
 
        //Create a new Mule Client
        MuleClient client = new MuleClient(muleContext);
 
        //These are the message properties that pass into the XQuery context
        Map props = new HashMap();
        props.put("ListTitle", "MyList");
        props.put("ListRating", new Integer(6));
 
        //Invoke the flow
        MuleMessage message = client.send("vm://test.in", srcData, props);
        assertNotNull(message);
        assertNull(message.getExceptionPayload());
        //Compare results
        assertTrue(XMLUnit.compareXML(message.getPayloadAsString(), resultData).similar());
    }
}