XML Converter for FIXEdge Java Endpoints
Starting from FIXEdge Java 1.13.0, a new feature has been introduced that enables seamless conversion between FIX and XML formats. This functionality is fully integrated into the Business Layer (BL) via Groovy scripting.
Feature Overview
Bidirectional conversion: Supports FIX-to-XML and XML-to-FIX transformations.
Dictionary-driven: Conversion logic relies on FIX dictionary definitions.
Scriptable: Usable directly in BL Groovy scripts for flexible routing and transformation.
Configurable: Includes a setting for handling unknown tags absent from the dictionary.
⚠️ Note: The XML converter is disabled by default and must be explicitly enabled in the configuration.
🔧Enabling the XML Converter
To enable XML conversion in FIXEdge Java:
Open the file:
[FEJ distribution]/conf/msg-converter.properties
Set the following property to true:
converter.dictionary.init = trueSet the following property to true or false:
converter.skipUnknownTag = falseWhen set to 'false', unknown tags are added to XML with an underscore before the tag name. For example, <_3366>value</_3366>. When set to 'true', unknown tags are skipped and not added to XML.
Open the file:
[FEJ distribution]/conf/spring/custom-ext.xml
In the section titled "Map for beans, which will be accessible in BL Groovy scripts", add the following entry:<entry key="xmlConverter" value-ref="xmlConverter"/>
<!-- Map for beans, which will be accessible in BL Groovy scripts -->
<util:map id="customBLBeans" key-type="java.lang.String">
<entry key="xmlConverter" value-ref="xmlConverter"/>
</util:map>Restart FIXEdge Java to apply the changes.
💡Examples of Business Layer configuration for XML converter
✅Example: Using XML Converter for custom FIX dictionary
The following example demonstrates a simple BL configuration that:
Uses custom FIX dictionary
FIXLatest-2for FIX to XML conversionConverts a FIX message from
session1(custom dictionaryFIXLatest-2) to XML and routes it to queueJMS_OUT_Qand topicJMS_OUT_T.
import com.epam.fej.converter.XmlConverter
import com.epam.fej.routing.RoutingContext
import com.epam.fej.routing.rules.MessageRoutingRule
import com.epam.fej.routing.rules.RuleAction
import com.epam.fej.routing.rules.SourceCondition
import groovy.xml.XmlSlurper
new MessageRoutingRule(
"Route msg with custom dictionary to JMS as XML",
{ params ->
def validSessions = ["session1"]
return validSessions.contains(params.getId())
} as SourceCondition,
null,
{ ctx ->
def xmlString = xmlConverter.convertFromFIX(ctx.getMessage(), "FIXLatest-2")
ctx.messageEvent.setHeader("JMS_BYTE_ARRAY", xmlString.getBytes("UTF-8"))
rc.getDestinationById("JMS_OUT_Q").each { adapter ->
adapter.send(ctx.messageEvent)
}
rc.getDestinationById("JMS_OUT_T").each { adapter ->
adapter.send(ctx.messageEvent)
}
ctx.exit()
} as RuleAction✅Example: Automatically Determining FIX Version for XML Conversion
The following example demonstrates a simple BL configuration that:
Does FIX to XML conversion for messages from the list of FIX sessions:
session1, session2, session3, session4.Automatically defines
fixVersionfor each FIX session / FIX message.Converts a FIX message using corresponding dictionary to XML and routes it to the topic
JMS_OUT_T.
new MessageRoutingRule(
"Route msg to JMS as XML",
{ params ->
def validSessions = ["session1", "session2", "session3", "session4"]
return validSessions.contains(params.getId())
} as SourceCondition,
null,
{ ctx ->
def fixVersion = "FIXLatest"
try {
if (ctx.sourceParams.&getAllSessionParams) {
def sessionParams = ctx.sourceParams.getAllSessionParams()
def fixVersionValue = sessionParams.getFixVersion().id
if (fixVersionValue == "FIXT11") {
fixVersion = sessionParams.getAppVersion().id
logger.debug("fixAppVersionId : ${fixVersion}")
} else {
fixVersion = fixVersionValue
}
logger.debug("fixVersionId : ${fixVersion}")
}
} catch (Exception e) {
logger.error("Error retrieving version info", e)
}
def xmlString = xmlConverter.convertFromFIX(ctx.getMessage(), fixVersion)
ctx.messageEvent.setHeader("JMS_BYTE_ARRAY", xmlString.getBytes("UTF-8"))
rc.getDestinationById("JMS_OUT_T").each { adapter ->
adapter.send(ctx.messageEvent)
}
ctx.exit()
} as RuleAction✅Example: Working with XML object in Business Rules
The following example demonstrates how to convert XML string to the XML object
import groovy.xml.XmlSlurper
new MessageRoutingRule(
"Route msg from JMS Queue",
{ params -> params.getId() == "JMS_IN_Q" },
null,
{ ctx ->
def fixFieldList = ctx.message
if (ctx.messageEvent.getHeader().containsKey("JMS_BYTE_ARRAY")) {
def parsed = new XmlSlurper().parseText(new String(ctx.messageEvent.getHeader("JMS_BYTE_ARRAY")))
String fixVersion = parsed.Header.BeginString.text()
if (fixVersion?.startsWith("FIXT")) {
fixVersion = parsed.Header.AppVersion
}
if (!fixVersion) {
try {
def sp = ctx?.destinationParams?.getAllSessionParams()
def fv = sp?.getFixVersion()?.id
fixVersion = (fv == "FIXT11") ? sp?.getAppVersion()?.id : fv
} catch (ignored) { /* no-op */ }
}
if (!fixVersion) fixVersion = "FIXLatest"
fixVersion=fixVersion.replaceAll("\\.", "")
logger.debug("fixVersion=${fixVersion}")
fixFieldList = xmlConverter.convertToFIX(
ctx.messageEvent.getHeader("JMS_BYTE_ARRAY"),
fixVersion
)
}
rc.getDestinationById("session2").each { adapter ->
adapter.send(fixFieldList)
}
ctx.exit()
} as RuleAction