Skip to content

Read Modes

Read modes define how content is extracted from the source message in a mapping rule. They control whether you read a single value, iterate over repetitions, concatenate multiple selectors, or use fixed literal values.

Overview

MyFormat supports five read modes, each designed for different data extraction patterns:

Read Mode Purpose Output Common Use Cases
SINGLE Read one value Single string Default mode for most field mappings
LITERAL Use fixed value Single string Constants, defaults, fixed text
CONCAT Combine multiple selectors Single string Building composite values from multiple fields
FOREACH Iterate over repetitions Multiple values Processing repeating elements, creating multiple target elements
FOREACH_CONCAT Aggregate repetitions Single string Combining repetitive data into one field

When to use each mode:

  • Use SINGLE for straightforward field-to-field mappings
  • Use LITERAL when you need to inject constant values or templates
  • Use CONCAT to build composite values from multiple source fields
  • Use FOREACH when you need to create multiple target elements from repetitive source data
  • Use FOREACH_CONCAT when you need to aggregate repetitive source data into a single target field

Default Behavior

If no read mode is specified, SINGLE is used by default.

SINGLE Mode

The SINGLE read mode is the default mode that reads a single value from the source message using the provided selector.

Syntax:

source_selector

Example 1: Basic field mapping

MappingTable table = new MappingTable(FileFormat.XML, FileFormat.CSV);

// Read single value from XML and write to CSV column
table.add(new MappingRule("/order/amount", "0"));

// Input XML:  <order><amount>1500.00</amount></order>
// Output CSV: 1500.00

Example 2: With transformation

MappingTable table = new MappingTable(FileFormat.MT, FileFormat.XML);

// Read field 32A amount and convert to decimal format
MappingRule rule = new MappingRule("32A/Amount", "/document/amount");
rule.addTransformation(new Transformation(Key.formatDecimal, "0.00"));
table.add(rule);

// Input MT:  :32A:231215EUR1500,
// Output XML: <document><amount>1500.00</amount></document>

LITERAL Mode

The LITERAL read mode allows you to specify a fixed value instead of reading from the source message. This is useful for injecting constants, defaults, or fixed text into the target message.

Syntax:

LITERAL(value)
"quoted value"

Syntax Variations

Literals can be defined using the LITERAL() function or simply with quoted text "value".

Example 1: Fixed constant

MappingTable table = new MappingTable(FileFormat.XML, FileFormat.CSV);

// Write fixed value to output
table.add(new MappingRule("LITERAL(USD)", "0"));
// Alternative: table.add(new MappingRule("\"USD\"", "0"));

// Output CSV: USD

Example 2: Default values when source is missing

MappingTable table = new MappingTable(FileFormat.JSON, FileFormat.XML);

// Try to read from source, use literal default if missing
table.add(new MappingRule("data.country", "/document/country"));
table.add(new MappingRule("LITERAL(UNKNOWN)", "/document/country", WriteMode.UPDATE));

// If data.country exists: uses that value
// If data.country missing: falls back to "UNKNOWN"

CONCAT Mode

The CONCAT read mode reads multiple selectors and concatenates their values into a single string. It can combine source fields with literal values to build composite content.

Syntax:

CONCAT(selector1, selector2, ...)
CONCAT(selector1, "literal", selector2, ...)

Example 1: Combining multiple fields

MappingTable table = new MappingTable(FileFormat.XML, FileFormat.CSV);

// Combine first name and last name with space separator
table.add(new MappingRule("CONCAT(/person/firstName, \" \", /person/lastName)", "0"));

// Input XML:  <person><firstName>John</firstName><lastName>Doe</lastName></person>
// Output CSV: John Doe

Example 2: Building composite identifiers

MappingTable table = new MappingTable(FileFormat.MT, FileFormat.CSV);

// Build reference from multiple MT fields with separators
table.add(new MappingRule("CONCAT(20, \"|\", 21, \"|\", 59/1)", "0"));

// Input MT with field 20=REF001, field 21=INV2023, field 59 account=ACC123
// Output CSV: REF001|INV2023|ACC123

Example 3: Adding prefixes/suffixes

MappingTable table = new MappingTable(FileFormat.JSON, FileFormat.XML);

// Add currency prefix to amount
table.add(new MappingRule("CONCAT(\"USD \", transaction.amount)", "/document/formattedAmount"));

// Input JSON:  {"transaction": {"amount": "1500.00"}}
// Output XML:  <document><formattedAmount>USD 1500.00</formattedAmount></document>

Example 4: Complex composition

MappingTable table = new MappingTable(FileFormat.XML, FileFormat.CSV);

// Build structured reference with date, type, and ID
table.add(new MappingRule(
    "CONCAT(/doc/date, \"-\", /doc/type, \"-\", /doc/id)", "0"));

// Input XML:  <doc><date>2025-12-30</date><type>INV</type><id>12345</id></doc>
// Output CSV: 2025-12-30-INV-12345

FOREACH Mode

The FOREACH read mode iterates over multiple repeating elements in the source message and processes each one individually. For each iteration, the target is written separately, creating multiple target elements.

Syntax:

FOREACH(nodeSelector)
FOREACH(nodeSelector, valueSelector)

The two-parameter form allows you to specify: - nodeSelector: Identifies the repeating elements to iterate over - valueSelector: Extracts specific content from each element (can be a sub-path or literal)

Example 1: Basic iteration

MappingTable table = new MappingTable(FileFormat.XML, FileFormat.CSV);

// Iterate over each item and write to separate CSV rows
table.add(new MappingRule("FOREACH(/order/items/item)", "0"));

// Input XML:
// <order>
//   <items>
//     <item>Widget</item>
//     <item>Gadget</item>
//     <item>Tool</item>
//   </items>
// </order>

// Output CSV:
// Widget
// Gadget
// Tool

Example 2: Two-parameter FOREACH with sub-path

MappingTable table = new MappingTable(FileFormat.XML, FileFormat.JSON);

// Iterate over transactions, extract specific field
table.add(new MappingRule("FOREACH(/report/transactions/tx, ./amount)", "amounts[{n}]"));

// Input XML:
// <report>
//   <transactions>
//     <tx><amount>100</amount><desc>Payment</desc></tx>
//     <tx><amount>200</amount><desc>Refund</desc></tx>
//   </transactions>
// </report>

// Output JSON: {"amounts": ["100", "200"]}

Example 3: FOREACH with transformations

MappingTable table = new MappingTable(FileFormat.XML, FileFormat.CSV);

// Iterate and apply transformation to each element
MappingRule rule = new MappingRule("FOREACH(/data/codes/code)", "0");
rule.addTransformation(new Transformation(Key.upperCase));
table.add(rule);

// Input XML:  <data><codes><code>abc</code><code>def</code><code>xyz</code></codes></data>
// Output CSV:
// ABC
// DEF
// XYZ

Example 4: Using literals in FOREACH

MappingTable table = new MappingTable(FileFormat.XML, FileFormat.CSV);

// Iterate over items but write the same literal value each time
table.add(new MappingRule("FOREACH(/order/items/item, \"ITEM\")", "1"));

// Input XML with 3 items creates 3 rows each with "ITEM" in column 1

Example 5: FOREACH with runtime variables in transformations

MappingTable table = new MappingTable(FileFormat.XML, FileFormat.CSV);

// Extract prefix from header
table.add(new MappingRule("/msg/header/code", "$prefix", WriteMode.VARIABLE));

// Apply dynamic prefix to each item
MappingRule rule = new MappingRule("FOREACH(/msg/items/item)", "0");
rule.addTransformation(new Transformation(Key.prepend, "[$prefix] "));
table.add(rule);

// Input XML:  <msg><header><code>TYPE-A</code></header><items><item>X</item><item>Y</item><item>Z</item></items></msg>
// Output CSV:
// [TYPE-A] X
// [TYPE-A] Y
// [TYPE-A] Z

FOREACH_CONCAT Mode

FOREACH_CONCAT is a read mode that iterates over multiple repeating elements and concatenates their values into a single string with a specified separator. Unlike FOREACH which creates multiple target elements, FOREACH_CONCAT produces one aggregated result.

Syntax:

FOREACH_CONCAT(selector, separator)
FOREACH_CONCAT(selector, separator, includeNulls)

Parameters:

Parameter Required Description
selector Yes Path to the repeating elements to aggregate
separator Yes String to insert between values (quoted)
includeNulls No true or false (default: false). When true, null values appear as empty strings in the result

Key characteristics:

  • Single output: All matched values are combined into one string
  • Order preserved: Values appear in document order
  • Transformations: Applied to the final concatenated result, not individual values
  • Variable support: Result can be stored in a variable with WriteMode.VARIABLE
  • Validation: Parameters are validated at compile time

Example 1: Basic aggregation from XML

Concatenate all item names from a repeating XML element:

MappingTable table = new MappingTable(FileFormat.XML, FileFormat.CSV);

table.add(new MappingRule("FOREACH_CONCAT(/order/items/item, \"|\")", "0"));

// Input XML:
// <order>
//   <items>
//     <item>Widget</item>
//     <item>Gadget</item>
//     <item>Tool</item>
//   </items>
// </order>

// Output CSV: Widget|Gadget|Tool

Example 2: Store aggregation in variable for reuse

Aggregate values once and use them multiple times:

MappingTable table = new MappingTable(FileFormat.XML, FileFormat.CSV);

// Aggregate into variable
table.add(new MappingRule("FOREACH_CONCAT(/invoice/lines/line/amount, \"+\")",
    "$allAmounts", WriteMode.VARIABLE));

// Use in multiple places
table.add(new MappingRule("$allAmounts", "0"));
table.add(new MappingRule("CONCAT(\"Total: \", $allAmounts)", "1"));

// Input: <invoice><lines><line><amount>100</amount></line><line><amount>200</amount></line></lines></invoice>
// Output column 0: 100+200
// Output column 1: Total: 100+200

Example 3: Apply transformation to aggregated result

Transform the concatenated string (transformation applies to final result, not individual values):

MappingTable table = new MappingTable(FileFormat.XML, FileFormat.CSV);

MappingRule rule = new MappingRule("FOREACH_CONCAT(/data/names/name, \", \")", "0");
rule.addTransformation(new Transformation(Key.upperCase));
table.add(rule);

// Input: <data><names><name>alice</name><name>bob</name></names></data>
// Output: ALICE, BOB

Example 4: Handling null values

Control how missing values are handled with the includeNulls parameter:

MappingTable table = new MappingTable(FileFormat.XML, FileFormat.CSV);

// With includeNulls=false (default): null values are skipped
table.add(new MappingRule("FOREACH_CONCAT(/data/items/item, \"|\")", "0"));
// Values [A, null, C] → "A|C"

// With includeNulls=true: null values appear as empty strings
table.add(new MappingRule("FOREACH_CONCAT(/data/items/item, \"|\", true)", "1"));
// Values [A, null, C] → "A||C"

Comparison: FOREACH vs FOREACH_CONCAT

Feature FOREACH FOREACH_CONCAT
Output Multiple values (one per iteration) Single concatenated string
Target creation Creates multiple target elements Creates one target element
Use with VARIABLE Not supported Supported
Transformations Applied per element Applied to final string
Use case Copy repetitions Aggregate repetitions

When to use FOREACH: - You need to create multiple target elements - Each source element should be independently transformed - You're mapping to repeating structures in the target

When to use FOREACH_CONCAT: - You need to combine multiple values into a single field - The target format doesn't support repetitions - You're building comma-separated lists or similar aggregations

Read Mode Comparison Table

Feature SINGLE LITERAL CONCAT FOREACH FOREACH_CONCAT
Input One selector Fixed value Multiple selectors Repeating elements Repeating elements
Output One value One value One value Multiple values One value
Selectors 1 0 2+ 1-2 1
Iterations No No No Yes Yes
Literal support No Yes Yes (in parameters) Yes (as value) No
Variable support Source + Transform Transform Source + Transform Transform only Full support
Target creation One element One element One element Multiple elements One element