Migrating the XML Module | MuleSoft Documentation
# 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` to `xml-module`
    * Consistency of return types
    * Syntax and UX changes
  * `xpath()` and `xpath3()` functions replaced by a new `XmlModule::xpath()` function
  * Improved error reporting for the schema validator
  * `schema-validation-filter` now replaced with `schema-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
Mule 3 Example: To use an XSL sheet in an external file
```
<mulexml:xslt-transformer xsl-file="cities-xslt.xsl" />
```

In Mule 4:
Mule 4 Example: To use an XSL sheet in an external file
```
<xml-module:xslt-transform>
  <xml-module:xslt>${file:::cities.xslt}</xml-module:xslt>
</xml-module:xslt-transform>
```

### Use Context Properties
Mule 3 Example: To set 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>
```

Mule 4 Example: To set context properties
```
<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 3 Example: To use the XPath extractor
```
<mule-xml:xpath-extractor-transformer expression="//book" resultType="STRING"/>
```

Mule 4 Example: To use the XPath extractor
```
<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.
Mule 3 Example: Using the xpath3 function
```
<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.


Mule 4 Example: Using the xpath function
```
<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:
Mule 3 Example: Using custom namespaces
```
 <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:
Mule 4 Example: Using custom namespaces
```
<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:
Mule 4 Example: Inline custom namespaces mapping
```
<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:
Mule 3 Example: Using XQuery transformer
```
<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:
Mule 4 Example: Using XQuery transformer
```
<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>
```
In Mule 4:
Mule 4 Example: Using XQuery transformer
```
<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:
Mule 3 Example: Schema validation filter
```
<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:
Mule 4 Example: Schema validator
```
<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>
```

## See also