Skip to content

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.VARIABLE with 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.VARIABLE before 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