<mulexml:xslt-transformer xsl-file="cities-xslt.xsl" />
Migrating the XML Module
A new XML module in Mule 4 replaces the one that was bundled in with Mule 3. The main changes are:
-
Removal of components and expressions, functions, and evaluators that were deprecated in Mule 3.6:
-
jxpath-filter
-
jaxen-filter
-
jxpath-extractor-transformer
-
is-xml-filter
-
xpath-filter
-
-
Changes to XPath, XSLT, and XQuery components to be consistent with the new Mule 4 components, mainly around:
-
DSL namespace prefix changed from
mxml
toxml-module
-
Consistency of return types
-
Syntax and UX changes
-
-
xpath()
andxpath3()
functions replaced by a newXmlModule::xpath()
function -
Improved error reporting for the schema validator
-
schema-validation-filter
now replaced withschema-validator
-
No longer tied to Java: It no longer uses SAX, StaX, or DOM types. Mule 4 is now strongly typed and we have mime type information about which data is in XML format. The runtime does the rest. All XML documents are represented as either Strings or streams. This means the following no longer exist (and are no longer needed):
-
dom-to-xml-transformer
-
dom-to-output-handler-transformer
-
xml-to-dom-transformer
-
xml-prettyprinter-transformer
-
jaxb-object-to-xml-transformer
-
jaxb-xml-to-object-transformer
-
jaxb-context
-
object-to-xml-transformer
-
xml-to-object-transformer
-
Migrating XSLT Operations
Use an XSL Style Sheet in an External File
In Mule 4:
<xml-module:xslt-transform>
<xml-module:xslt>${file:::cities.xslt}</xml-module:xslt>
</xml-module:xslt-transform>
Use Context Properties
<mulexml:xslt-transformer xsl-file="cities-result-document-xslt.xsl">
<mulexml:context-property key="output_location" value="#[flowVars['outputFile']" />
<mulexml:context-property key="user_id" value="#[flowVars['userId']" />
</mulexml:xslt-transformer>
<xml-module:xslt-transform>
<xml-module:xslt>${file::cities.xslt}</xml-module:xslt>
<xml-module:context-properties>#[{'output_location': vars.outputFile, 'user_id': vars.userId}]</xml-module:context-properties>
</xml-module:xslt-transform>
Migrating XPath Operations and Expressions
Use the XPath Extractor Transformer
The XPath extractor no longer supports custom resultType
parameter. It will now always return a List of Strings with all the matching elements.
<mule-xml:xpath-extractor-transformer expression="//book" resultType="STRING"/>
<xml-module:xpath-extract xpath="//book" />
Use the XPath Expression Function
Mule 3 originally had an xpath()
MEL function. In Mule 3.6, it was deprecated in favor of a new xpath3()
function. Now, both functions are replaced by a new XmlModule::xpath()
DataWeave function, which becomes available when the module is added to an application.
<set-payload value="#[xpath3('//book', payload, 'NODESET')]" />
Mule 3’s xpath3()
function allowed you to specify the XPath expression and the input value, and it gave different options in terms of the expected output: BOOLEAN
, STRING
, NUMBER
, NODESET
or NODE
, where NODESET
and NODE
required understanding of Java’s representation of a DOM tree.
The new function also accepts the XPath expression and the input, but differs in these ways:
-
It adds support for custom context properties.
-
It does not allow specification of the output type. It will always return a List of Strings, just as
<xml-module:xpath-extract>
does.
<set-payload value="#[XmlModule::xpath('//book', payload, {})]" />
You can use this function inside any DataWeave transformation. |
Use XPath with Custom Namespaces
In Mule 3, a <mxml:namespace-manager>
is needed to map custom namespaces prefixes:
<mulexml:namespace-manager includeConfigNamespaces="true">
<mulexml:namespace prefix="soap" uri="http://schemas.xmlsoap.org/soap/envelope/"/>
<mulexml:namespace prefix="mule" uri="http://simple.component.mule.org/"/>
</mulexml:namespace-manager>
<flow name="xpathWithNamespace">
<expression-transformer expression="xpath3('/soap:Envelope/soap:Body/mule:echo/mule:echo')" />
</flow>
This approach has the limitation that only one namespace-manager could be used per application. In Mule 4, you can declare as many namespace-directory
elements as you want, and then reference the one you need on each operation:
<xml-module:namespace-directory name="fullNs">
<xml-module:namespaces>
<xml-module:namespace prefix="soap" uri="http://schemas.xmlsoap.org/soap/envelope/"/>
<xml-module:namespace prefix="mule" uri="http://simple.component.mule.org/"/>
</xml-module:namespaces>
</xml-module:namespace-directory>
<flow name="xpathWithFullNs">
<xml-module:xpath-extract xpath="/soap:Envelope/soap:Body/mule:echo/mule:echo" namespaceDirectory="fullNs"/>
</flow>
Additionally, you could even choose not to declare a 'namespace-directory' and instead just map the namespace inline:
<flow name="xpathWithFullNs">
<xml-module:xpath-extract xpath="/soap:Envelope/soap:Body/mule:echo/mule:echo">
<xml-module:namespaces>
<xml-module:namespace prefix="soap" uri="http://schemas.xmlsoap.org/soap/envelope/"/>
<xml-module:namespace prefix="mule" uri="http://simple.component.mule.org/"/>
</xml-module:namespaces>
</xml-module:xpath-extract>
</flow>
Migrating XQuery Operations
The main difference is that in Mule 3, the output type of this transformer would depend on the result of the transformation:
-
If the transformation generates many elements, a List is returned.
-
Depending on the transformation, the elements of that list could be String or some generic Java representation, such as a
Node
. -
If the transformation generates only one element, it returns that element.
In Mule 4, this will always return a List of Strings.
Other than that, changes are around syntax only:
<mxml:xquery-transformer>
<mxml:context-property key="books" value="#[flowVars['books']]" />
<mxml:context-property key="cities" value="#[flowVars['cities']]" />
<mxml:xquery-text>
<![CDATA[
xquery version "3.0";
declare variable $document external;
declare variable $cities external;
declare variable $books external;
<mixes>
{
for $b in $books/BOOKLIST/BOOKS/ITEM,
$c in $cities/cities/city
return <mix title="{$b/TITLE/text()}" city="{$c/@name}" />
}
</mixes>
]]>
</mxml:xquery-text>
</mxml:xquery-transformer>
In Mule 4:
<xml-module:xquery-transform>
<xml-module:xquery>
<![CDATA[
xquery version "3.0";
declare variable $document external;
declare variable $cities external;
declare variable $books external;
<mixes>
{
for $b in fn:doc($books)/BOOKLIST/BOOKS/ITEM,
$c in fn:doc($cities)/cities/city
return <mix title="{$b/TITLE/text()}" city="{$c/@name}" />
}
</mixes>
]]>
</xml-module:xquery>
<xml-module:context-properties>#[{'books' : vars.books, 'cities': vars.cities}] </xml-module:context-properties>
</xml-module:xquery-transform>
Validating XML Against a Schema
In Mule 3, a filter was used to validate schemas:
<mxml:schema-validation-filter schemaLocations="schema1.xsd, schema2.xsd"/>
If the validation fails, the message is dropped.
In Mule 4, we replaced filters with validators:
<xml-module:validate-schema schemas="schema1.xsd, schema2.xsd"/>
This validator will raise an XML-MODULE:SCHEMA_NOT_HONOURED
error.
Installing the XML Module
To use the XML module, simply add it to your application using the Studio palette, or add the following dependency in your pom.xml
file:
<dependency>
<groupId>org.mule.modules</groupId>
<artifactId>mule-xml-module</artifactId>
<version>1.1.0</version> <!-- or newer -->
<classifier>mule-plugin</classifier>
</dependency>