Write Modes
Write modes define how the translated content is written to the target message. They control whether to create new elements, update existing ones, append to them, or store values in runtime variables for later use.
Overview
MyFormat supports five write modes, each designed for different target writing patterns:
| Write Mode | Purpose | Behavior | Common Use Cases |
|---|---|---|---|
| CREATE | Add new element | Always creates a new element | Default mode for most mappings |
| UPDATE | Overwrite existing | Updates if exists, creates if missing | Updating known fields, ensuring single values |
| APPEND | Add to existing | Appends to existing, creates if missing | Building multi-line content, accumulating values |
| SETUP | Configure translation | Sets translation parameters | Defining formats, types, encoding |
| VARIABLE | Store for reuse | Stores value in variable | Intermediate calculations, reusing values |
When to use each mode:
- Use CREATE when you want to always add new content (default behavior)
- Use UPDATE when you need to ensure a single value and overwrite any existing content
- Use APPEND when building composite content from multiple rules
- Use SETUP to configure the translation engine (formats, types, options)
- Use VARIABLE to store intermediate values for reuse across multiple rules
Default Behavior
If no write mode is specified, CREATE is used by default.
CREATE Mode
The CREATE write mode always creates a new element in the target message, regardless of whether an element already exists at that location. This is the default behavior when no write mode is specified.
When to use: Most field-to-field mappings where you want to add content.
Example 1: Basic field creation
MappingTable table = new MappingTable(FileFormat.CSV, FileFormat.XML);
// Create new XML elements from CSV columns
table.add(new MappingRule("0", "/order/id")); // Creates <id>
table.add(new MappingRule("1", "/order/amount")); // Creates <amount>
table.add(new MappingRule("2", "/order/currency")); // Creates <currency>
// Input CSV: 12345,1500.00,USD
// Output XML:
// <order>
// <id>12345</id>
// <amount>1500.00</amount>
// <currency>USD</currency>
// </order>
Example 2: Creating repetitive elements
MappingTable table = new MappingTable(FileFormat.CSV, FileFormat.XML);
// Using FOREACH to create multiple item elements
table.add(new MappingRule("FOREACH(items[{n}])", "/order/item"));
// Each iteration creates a new <item> element
// Input CSV with items array creates multiple <item> elements
Example 3: Explicit CREATE mode
MappingTable table = new MappingTable(FileFormat.XML, FileFormat.MT);
// Explicitly specify CREATE mode (though it's the default)
table.add(new MappingRule("/data/reference", "20", WriteMode.CREATE));
table.add(new MappingRule("/data/amount", "32A/Amount", WriteMode.CREATE));
// Each rule creates a new field in the MT message
UPDATE Mode
The UPDATE write mode checks if the target element exists before writing. If found, it overwrites the existing value. If not found, it creates a new element (behaves like CREATE).
When to use: When you need to ensure a single value exists and want to overwrite any prior value.
Example 1: Ensuring single values
MappingTable table = new MappingTable(FileFormat.CSV, FileFormat.XML);
// First rule creates the element
table.add(new MappingRule("0", "/doc/status", WriteMode.CREATE));
// Second rule updates the same element (overwrites previous value)
table.add(new MappingRule("1", "/doc/status", WriteMode.UPDATE));
// Input CSV: PENDING,APPROVED
// Output XML: <doc><status>APPROVED</status></doc>
// (Only the final value is present)
Example 2: Conditional updates with defaults
MappingTable table = new MappingTable(FileFormat.JSON, FileFormat.XML);
// Set default value
table.add(new MappingRule("LITERAL(UNKNOWN)", "/doc/country", WriteMode.CREATE));
// Update with actual value if present in source
table.add(new MappingRule("data.country", "/doc/country", WriteMode.UPDATE));
// If data.country exists: overwrites "UNKNOWN" with actual value
// If data.country missing: keeps "UNKNOWN"
Example 3: Priority-based field selection
MappingTable table = new MappingTable(FileFormat.MT, FileFormat.XML);
// Try multiple source fields in priority order
table.add(new MappingRule("50A/Account", "/doc/account", WriteMode.CREATE));
table.add(new MappingRule("50K/Account", "/doc/account", WriteMode.UPDATE));
table.add(new MappingRule("50F/Account", "/doc/account", WriteMode.UPDATE));
// Uses first available field, subsequent rules update if their sources exist
Example 4: Merging from multiple sources
MappingTable table = new MappingTable(FileFormat.CSV, FileFormat.JSON);
// Start with first column
table.add(new MappingRule("0", "result.combined", WriteMode.CREATE));
// Replace with second column if not empty
table.add(new MappingRule("1", "result.combined", WriteMode.UPDATE));
// Replace with third column if not empty
table.add(new MappingRule("2", "result.combined", WriteMode.UPDATE));
// Uses the last non-empty value among the three columns
APPEND Mode
The APPEND write mode checks if the target element exists. If found, it appends the new value to the existing content. If not found, it creates a new element (behaves like CREATE).
When to use: Building multi-line content, accumulating values, or creating composite fields from multiple rules.
Example 1: Building multi-line narrative
MappingTable table = new MappingTable(FileFormat.CSV, FileFormat.MT);
// Build field 72 narrative from multiple CSV columns
table.add(new MappingRule("0", "72", WriteMode.CREATE));
table.add(new MappingRule("LITERAL(\"\\n\")", "72", WriteMode.APPEND)); // Line break
table.add(new MappingRule("1", "72", WriteMode.APPEND));
table.add(new MappingRule("LITERAL(\"\\n\")", "72", WriteMode.APPEND)); // Line break
table.add(new MappingRule("2", "72", WriteMode.APPEND));
// Input CSV: Line1,Line2,Line3
// Output MT field 72:
// Line1
// Line2
// Line3
Example 2: Accumulating values with separators
MappingTable table = new MappingTable(FileFormat.XML, FileFormat.CSV);
// Combine first and last name
table.add(new MappingRule("/person/firstName", "0", WriteMode.CREATE));
table.add(new MappingRule("LITERAL(\" \")", "0", WriteMode.APPEND));
table.add(new MappingRule("/person/lastName", "0", WriteMode.APPEND));
// Input XML: <person><firstName>John</firstName><lastName>Doe</lastName></person>
// Output CSV: John Doe
Example 3: Building structured content
MappingTable table = new MappingTable(FileFormat.MT, FileFormat.JSON);
// Build a summary field from multiple MT fields
table.add(new MappingRule("20", "summary", WriteMode.CREATE));
table.add(new MappingRule("LITERAL(\" | \")", "summary", WriteMode.APPEND));
table.add(new MappingRule("32A/Currency", "summary", WriteMode.APPEND));
table.add(new MappingRule("LITERAL(\" \")", "summary", WriteMode.APPEND));
table.add(new MappingRule("32A/Amount", "summary", WriteMode.APPEND));
// Input MT with 20=REF123, 32A=230101USD1000
// Output JSON: {"summary": "REF123 | USD 1000"}
Example 4: Conditional appending
MappingTable table = new MappingTable(FileFormat.XML, FileFormat.CSV);
// Start with mandatory field
table.add(new MappingRule("/order/id", "0", WriteMode.CREATE));
// Append optional fields if present
table.add(new MappingRule("LITERAL(\"-\")", "0", WriteMode.APPEND));
table.add(new MappingRule("/order/type", "0", WriteMode.APPEND));
// If type exists: "12345-INVOICE"
// If type missing: "12345-" (separator still appended)
SETUP Mode
The SETUP write mode is used to configure the translation engine rather than write to the target message. Setup commands define properties like source/target formats, message types, encoding, and other translation parameters.
When to use: At the beginning of your mapping table to configure how the translation should behave.
Setup Commands Documentation
For a complete list of available setup commands, see Setup Commands.
Example 1: Basic format configuration
MappingTable table = new MappingTable();
// Define source and target formats
table.add(new MappingRule("CSV", "sourceFormat", WriteMode.SETUP));
table.add(new MappingRule("MT", "targetFormat", WriteMode.SETUP));
// Now add regular mapping rules
table.add(new MappingRule("0", "20"));
table.add(new MappingRule("1", "32A/Amount"));
Example 2: MX message type setup
MappingTable table = new MappingTable(FileFormat.CSV, FileFormat.MX);
// Specify MX message type
table.add(new MappingRule("LITERAL(\"pacs.008.001.08\")", "mxType", WriteMode.SETUP));
// Add mapping rules for pacs.008 fields
table.add(new MappingRule("0", "/Document/FIToFICstmrCdtTrf/GrpHdr/MsgId"));
Example 3: Fixed-length record template
MappingTable table = new MappingTable(FileFormat.CSV, FileFormat.FIXED);
// Define fixed-length record structure
table.add(new MappingRule("HR,,,,,,,,", "HR", WriteMode.SETUP));
table.add(new MappingRule("DT,10,20,30,40", "DT", WriteMode.SETUP));
// Map CSV columns to fixed-length positions
table.add(new MappingRule("0", "DT/0"));
table.add(new MappingRule("1", "DT/1"));
VARIABLE Mode
The VARIABLE write mode stores the translated value in a runtime variable instead of writing to the target message. Variables are prefixed with $ and can be referenced in subsequent rules' source selectors, CONCAT expressions, and transformation parameters.
When to use: - Avoiding repeated expensive operations (transformations, lookups) - Building complex identifiers from multiple parts - Storing intermediate values for multi-step transformations - Reusing the same value in multiple target locations
Variable Scope
Variables exist only during a single translate() call and must be defined before use.
Key Characteristics
- Scope: Variables exist only during a single
translate()call - Syntax: Variable names must start with
$(e.g.,$myVar,$amount,$reference) - Definition: Use
WriteMode.VARIABLEwith a variable name as target - Usage: Variables can be used in source selectors, CONCAT expressions, and transformation parameters
- Order: Variables must be defined before use (validated at compile time)
- Read Modes: Variables work with all read modes:
- LITERAL, SINGLE, CONCAT: Variables supported in source and transformation parameters
- FOREACH, FOREACH_CONCAT: Variables supported in transformation parameters only (not in selectors)
Example 1: Reusing a transformed value
Extract once, transform once, use multiple times to avoid repeating expensive operations:
MappingTable table = new MappingTable(FileFormat.MT, FileFormat.MX);
// Extract and format amount once
table.add(new MappingRule("32A/Amount", "$formattedAmount", WriteMode.VARIABLE,
new Transformation(Key.formatDecimal, "0.00")));
// Use in multiple places
table.add(new MappingRule("$formattedAmount", "/Document/TtlIntrBkSttlmAmt"));
table.add(new MappingRule("CONCAT(\"USD \", $formattedAmount)", "/Document/Summary"));
table.add(new MappingRule("$formattedAmount", "/Document/ChargedAmount",
new Transformation(Key.multiply, "1.02"))); // Add 2% markup
Example 2: Building complex identifiers
Construct reference numbers from multiple parts and format them differently for various outputs:
MappingTable table = new MappingTable(FileFormat.MT, FileFormat.MX);
// Extract components
table.add(new MappingRule("20C/SEME", "$senderRef", WriteMode.VARIABLE));
table.add(new MappingRule("21/RelatedRef", "$relatedRef", WriteMode.VARIABLE));
table.add(new MappingRule("LITERAL(\"2025\")", "$year", WriteMode.VARIABLE));
// Combine in different formats for different target fields
table.add(new MappingRule("CONCAT($year, \"-\", $senderRef, \"-\", $relatedRef)",
"/Document/InternalReference"));
table.add(new MappingRule("CONCAT($senderRef, \"/\", $year)", "/Document/ExternalReference"));
Example 3: Variables in transformation parameters
Use variables to enable dynamic transformation behavior based on previously extracted values:
MappingTable table = new MappingTable(FileFormat.MT, FileFormat.CSV);
// Extract the account number to use as replacement
table.add(new MappingRule("59/Account", "$accountNumber", WriteMode.VARIABLE));
// Replace placeholder in a template field with the account number
MappingRule rule = new MappingRule("72/Narrative", "1");
rule.addTransformation(new Transformation(Key.replace, "{ACCOUNT}", "$accountNumber"));
table.add(rule);
// Input MT: 72: "Transfer to account {ACCOUNT} completed"
// Output CSV: "Transfer to account 123456789 completed"
Example 4: Dynamic prefix from source message
Format values with dynamic prefixes or suffixes extracted from the same message:
MappingTable table = new MappingTable(FileFormat.MT, FileFormat.CSV);
// Extract currency from field 32A
table.add(new MappingRule("32A/Currency", "$ccy", WriteMode.VARIABLE));
// Format amount with currency prefix
MappingRule amountRule = new MappingRule("32A/Amount", "0");
amountRule.addTransformation(new Transformation(Key.prepend, "$ccy "));
table.add(amountRule);
// Input MT: :32A:230101USD1000,00
// Output CSV: USD 1000,00
Supported Transformations with Variables
Variables can be used in any String parameter of transformations, including:
prepend($prefix),append($suffix)replace($search, $replacement)substringBetween($open, $close)defaultString($default)map($key, $value)ifElse($condition, $then, $else)ifMatches($pattern),ifNotMatches($pattern)leftPad(size, $padChar),rightPad(size, $padChar)- And all other transformations accepting String parameters
Limitation
Integer parameters (like size in leftPad) cannot be replaced with variables. Only String parameters support variable substitution.
Variable Validation
The MyFormat validator checks variable usage at compile time:
- Variables must be defined with
WriteMode.VARIABLEbefore use - Variable names must start with
$ - Variables used in source selectors or transformations must have been defined in earlier rules
Example validation error:
Rule 3: transformation 'prepend' uses undefined variable '$prefix'. Variables must be defined before use.
This compile-time validation catches typos and ordering issues before runtime, preventing silent failures.
Write Mode Comparison Table
| Feature | CREATE | UPDATE | APPEND | SETUP | VARIABLE |
|---|---|---|---|---|---|
| Purpose | Add new | Overwrite | Accumulate | Configure | Store |
| Writes to target | Yes | Yes | Yes | No | No |
| Creates if missing | Yes | Yes | Yes | N/A | N/A |
| Updates if exists | No | Yes | No | N/A | N/A |
| Appends if exists | No | No | Yes | N/A | N/A |
| Default mode | Yes | No | No | No | No |
| Can use variables | Yes (source) | Yes (source) | Yes (source) | Yes (source) | N/A |
| Common use case | Standard mapping | Ensuring single value | Building composite | Initialization | Reusing values |