The standard data types for <property> and <parameter> are primitive types: string, boolean, number, date, datetime, localdatetime, time, localtime, timezone, binary, any, regex.
To define types that with more complex structures than the primitive types, you can create a catalog of data types that you inject into the module. This example creates a catalog file (hello-smart-connector/smart-connector/src/main/resources/module-Hello-catalog.xml) with the following content:
<?xml version="1.0" encoding="UTF-8"?>
<catalogs xmlns="http://www.mulesoft.org/schema/mule/types" >
<catalog name="PersonXsdType" format="application/xml">
<schema format="application/xml+schema" location="./person-schema.xsd" />
</catalog>
<catalog name="PersonJsonType" format="application/json">
<schema format="application/json+schema" location="./person-schema.json" />
</catalog>
</catalogs>
The catalog file references XSD and JSON schema files:
-
person-schema.xsd, which contains the following content:
<xs:schema targetNamespace="http://uri" attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Person">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="name"/>
<xs:element type="xs:string" name="lastName"/>
<xs:element type="xs:integer" name="age"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
-
person-schema.json, which contains the following content:
{
"type": "object",
"properties": {
"age": {
"type": "integer"
},
"name": {
"type": "string"
},
"lastname": {
"type": "string"
}
},
"additionalProperties": false
}
So, the structure of the tree hello-smart-connector/smart-connector folder looks like this:
➜ ~ tree hello-smart-connector/smart-connector
hello-smart-connector/smart-connector
├── pom.xml
└── src
└── main
└── resources
├── module-Hello-catalog.xml
├── module-Hello.xml
├── person-schema.json
└── person-schema.xsd
Once the schemas are ready, you use types they define by referencing the associated catalogs (PersonXsdType and PersonJsonType), for example:
<module name="Hello XML SDK" prefix="module-hello" ... >
...
<operation name="person-xml-to-json" doc:description="Takes a Person in XML format and translates it to JSON">
<parameters>
<parameter name="content" type="PersonXsdType::{http://uri}Person"/>
</parameters>
<body>
<ee:transform>
<ee:set-payload><![CDATA[
%dw 2.0
%output application/json encoding='UTF-8'
---
{
"name" : vars.content.person.name,
"lastname" : vars.content.person.lastName,
"age" : vars.content.person.age as Number
}
]]></ee:set-payload>
</ee:transform>
</body>
<output type="PersonJsonType"/>
</operation>
<operation name="person-json-to-xml" doc:description="Takes a Person in JSON format and translates it to XML">
<parameters>
<parameter name="content" type="PersonJsonType"/>
</parameters>
<body>
<ee:transform>
<ee:set-payload><![CDATA[
%dw 2.0
%output application/xml
---
person : vars.content
]]></ee:set-payload>
</ee:transform>
</body>
<output type="PersonXsdType::{http://uri}Person"/>
</operation>
<module/>
Notice that the value of the type attribute for the JSON schema is the name of the catalog that contains that schema (PersonJsonType). However, for the XML schema, the value of the type attribute appends two colons :: and the qname (qualified name) reference to the Person element: PersonXsdType::{http://uri}Person.
To perform the DataWeave transformation from JSON to XML (shown within <ee:transform/>), it is necessary to add the following dependency to the POM file so that the module can find the required schema (mule-ee.xsd):
<dependency>
<groupId>com.mulesoft.mule.runtime.modules</groupId>
<artifactId>mule-module-spring-config-ee</artifactId>
<version>${mule.version}</version>
<scope>provided</scope>
</dependency>
To use the operations from the example above in a Mule app, it is necessary to feed values to them, for example:
<mule ...>
<flow name="person-xml-2-json-flow">
<!-- create an XML Person and store it in the payload -->
<ee:transform>
<ee:set-payload><![CDATA[
%dw 2.0
%output application/xml
---
person : {
name : "Lautaro",
lastName: "Fernandez",
age : 54
}
]]></ee:set-payload>
</ee:transform>
<!-- call the operation -->
<module-hello:person-xml-to-json content="#[payload]"/>
<!-- at this point, the payload is a JSON Person -->
</flow>
<flow name="person-json-2-xml-flow">
<!-- create a JSON Person and store it in the payload -->
<ee:transform>
<ee:set-payload><![CDATA[
%dw 2.0
%output application/json
---
{
name : "Lautaro",
lastName: "Fernandez",
age : 54
}
]]></ee:set-payload>
</ee:transform>
<!-- call the operation -->
<module-hello:person-json-to-xml content="#[payload]"/>
<!-- at this point, the payload is an XML Person -->
</flow>
</mule>
When parameterizing values that are not primitive types, the defined <operation> can declare them as role="CONTENT" so that it is not mandatory to use an additional processor in the <flow> to call the operation. The person-xml-to-json operation in this example adds this attribute to the content parameter:
<module name="Hello XML SDK" prefix="module-hello" ... >
...
<operation name="person-xml-to-json" doc:description="Takes a Person in XML format and translates it to JSON">
<parameters>
<parameter name="content" type="PersonXsdType::{http://uri}Person" role="CONTENT"/>
</parameters>
<body>
<ee:transform>
<ee:set-payload><![CDATA[
%dw 2.0
%output application/json encoding='UTF-8'
---
{
"name" : vars.content.person.name,
"lastname" : vars.content.person.lastName,
"age" : vars.content.person.age as Number
}
]]></ee:set-payload>
</ee:transform>
</body>
<output type="PersonJsonType"/>
</operation>
...
<module/>
To use the operations from the example above in a Mule app, it is necessary to feed values to them, for example:
<mule ...>
<flow name="person-xml-2-json-using-content-flow">
<!-- call the operation -->
<module-hello:person-xml-to-json>
</module-hello:content><![CDATA[
%dw 2.0
%output application/xml
---
person : {
name : "Lautaro",
lastName: "Fernandez",
age : 54
}]]>
</module-hello:content>
</module-hello:person-xml-to-json>
<!-- at this point, the payload is a JSON Person -->
</flow>
..
</mule>