FHIR Mapping Language (FML)
0.1.0 - STU 1 International flag

FHIR Mapping Language (FML), published by HL7 International / FHIR Infrastructure. This guide is not an authorized publication; it is the continuous build for version 0.1.0 built by the FHIR (HL7® FHIR® Standard) CI Build. This version is based on the current content of https://github.com/HL7/mapping-language-ig/ and changes regularly. See the Directory of published versions

FML Annotated Examples

Page standards status: Informative

This page provides minimal self-contained examples of every feature of the FHIR Mapping Language. Each example is a complete, parseable FML file demonstrating a single feature.

Note: There are several bugs in the IG Publisher that prevent some features from being used, and as such they do not render correctly on this page.

Feature Coverage

Feature Example
Metadata Basic
  Extended
Uses Source and Target
  Alias
  Queried and Produced
Other Headers/Syntax Imports
  Constants
  Embedded ConceptMap
  Backtick Identifiers
  Round-trippable comments
Group Basic
  Extends
  Types
  Type Plus
Simple Identity Transform
  Batch Identity
Source Simple Copy
  Type Filter
  Cardinality
  Default Value
  List First
  List Last
  List Not First
  List Not Last
  List Only One
  Where Condition
  Check Condition
  Log Statement
  Multiple Sources
Target List Modes
  Multiple Targets
  Sub-Element
  Using FHIRPath as a source
Transform create
  truncate
  cast
  append
  translate
  reference
  evaluate
  cc
  c
  qty
  id
  cp
  uuid
Dependent Inline Rules
  Group Invocation
  Multiple Groups
Structure Property to Array
  Array to Property
  Array to Array
  Nested to Top Level
  Top Level to Nested

Metadata

Metadata - Basic

example: metadata-basic.fml

Every map requires url, name, and status metadata.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/MetadataBasic'
/// name = 'MetadataBasic'
/// status = 'active'
/// description = 'Example demonstrating required metadata: url, name, and status'

uses "http://hl7.org/fhir/StructureDefinition/Basic" as source
uses "http://hl7.org/fhir/StructureDefinition/Basic" as target

group MetadataBasic(source src : Basic, target tgt : Basic) {
  src.id as v -> tgt.id = v;
}

Metadata - Extended

example: metadata-extended.fml

Maps can include title, experimental flag, jurisdiction, and multi-line markdown description.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/MetadataExtended'
/// name = 'MetadataExtended'
/// title = 'Extended Metadata Example'
/// status = 'active'
/// description = """
This is a **multi-line** markdown description.
It demonstrates the extended metadata capabilities.
"""
/// experimental = true

uses "http://hl7.org/fhir/StructureDefinition/Basic" as source
uses "http://hl7.org/fhir/StructureDefinition/Basic" as target

// Bug: parser rejects complex metadata (jurisdiction) per spec
// /// jurisdiction =
// /// jurisdiction.coding =
// /// jurisdiction.coding.system = "urn:iso:std:iso:3166"
// /// jurisdiction.coding.code = "US"
group MetadataExtended(source src : Basic, target tgt : Basic) {
  src.id as v -> tgt.id = v;
}

Uses

Uses - Source and Target

example: uses-source-target.fml

The uses declaration references structure definitions and declares their role as source or target.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/UsesSourceTarget'
/// name = 'UsesSourceTarget'
/// status = 'active'
/// description = 'Example demonstrating basic source and target uses declarations'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group UsesSourceTarget(source src : Patient, target tgt : Patient) {
  src.id as v -> tgt.id = v "r1";
}

Uses - Alias

example: uses-alias.fml

An alias provides an alternate name for a type when source and target share the same type name.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/UsesAlias'
/// name = 'UsesAlias'
/// status = 'active'
/// description = 'Example demonstrating the alias keyword for uses declarations'

uses "http://hl7.org/fhir/StructureDefinition/Patient" alias PatientR3 as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group UsesAlias(source src : PatientR3, target tgt : Patient) {
  src.id as v -> tgt.id = v "r1";
}

Uses - Queried and Produced

example: uses-queried-produced.fml

The queried mode references lookups during mapping; produced references types created as side-effects.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/UsesQueriedProduced'
/// name = 'UsesQueriedProduced'
/// status = 'active'
/// description = 'Example demonstrating queried and produced modes in uses declarations - Only demonstrates produced, doesn\'t demonstrate queried.'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Bundle" as target
uses "http://hl7.org/fhir/StructureDefinition/HumanName" as produced

group UsesQueriedProduced(source src : Patient, target tgt : Patient) {
  src.id as v -> tgt.id = v "r1";
  src.name as v -> tgt.name = create('HumanName') as tn then {
    v.family as f -> tn.family = f "setFamily";
    v.given as f -> tn.given = f "setGiven";
  } "r2";
}

Other Headers/Syntax

Imports

example: imports.fml

The imports statement includes other maps; wildcards (*) allow bulk import.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/Imports'
/// name = 'Imports'
/// status = 'active'
/// description = 'Example demonstrating the imports statement with wildcard support'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

imports "http://hl7.org/fhir/uv/fml/StructureMap/Helper*"

group Imports(source src : Patient, target tgt : Patient) {
  src.id as v -> tgt.id = v;
}

Constants

example: constants.fml

The let keyword defines reusable constants available as variables in all rules.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/Constants'
/// name = 'Constants'
/// status = 'active'
/// description = 'Example demonstrating reusable constants defined with the let keyword'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

let defaultSystem = 'http://example.org/systems/id';
let maxLen = 20;

group Constants(source src : Patient, target tgt : Patient) {
  src.id as v -> tgt.id = truncate(v, maxLen) "r1";
}

Embedded ConceptMap

example: conceptmap-embedded.fml

A ConceptMap can be embedded directly in the mapping file and referenced by local id.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/ConceptMapEmbedded'
/// name = 'ConceptMapEmbedded'
/// status = 'active'
/// description = 'Example Map to demonstrate an embedded ConceptMap'

conceptmap "GenderMap" {
  prefix s = "http://hl7.org/fhir/administrative-gender"
  prefix t = "http://terminology.hl7.org/CodeSystem/v2-0001"

  s:male - t:M
  s:female - t:F
  s:other - t:O
  s:unknown - t:U
}

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group ConceptMapEmbedded(source src : Patient, target tgt : Patient) {
  src.gender as v -> tgt.gender = translate(v, '#GenderMap', 'code') "r1";
}

Syntax - Backtick Identifiers

example: syntax-backticks.fml

Element names from the data model that conflict with reserved words or contain special characters can be escaped with backticks.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/SyntaxBackticks'
/// name = 'SyntaxBackticks'
/// status = 'active'
/// description = 'Example demonstrating backtick-escaped identifiers for reserved words and special characters'

uses "http://hl7.org/fhir/StructureDefinition/Basic" as source
uses "http://hl7.org/fhir/StructureDefinition/Basic" as target

group SyntaxBackticks(source src : Basic, target tgt : Basic) {
  // backticks allow reserved words and special chars as element names
  src.`group!` as v -> tgt.`group#` = v;
  src.`section4.5` as v -> tgt.`section4.5` = v;
  src.`section4.6` as v -> tgt.`section4.6` = v "nextSection";
}

Comments - where FML supports round trippable comments with StructureMap

example: comments.fml

Although FML can have comments pretty much anywhere, the StructureMap resource doesn't handle that, and this example shows all the places it can hold documentation in comments

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/Comments'
/// name = 'Comments'
/// status = 'active'
/// description = 'Example demonstrating the use of comments in FML'

// comment on source structure import
uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
// comment on target structure import
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

// This is a comment on the group
group CommentsDemo(source src : Patient, target tgt : Patient) {
  // A comment preceding a rule R1
  // with more than one line
  src.birthDate -> tgt.birthDate "R1";
  src.active -> tgt.active "R2";
  src.name as v -> tgt.name as tn then {
    // before R3 comment
    v.family -> tn.family "R3";
  } "R4";
}

Group

Group - Basic

example: group-basic.fml

A group defines a named set of rules with typed source and target parameters.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/GroupBasic'
/// name = 'GroupBasic'
/// status = 'active'
/// description = 'Example demonstrating a basic group with typed source and target parameters'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group GroupBasic(source src : Patient, target tgt : Patient) {
  src.id as v -> tgt.id = v;
  src.active as v -> tgt.active = v;
}

Group - Extends

example: group-extends.fml

A group can extends another group, inheriting its rules.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/GroupExtends'
/// name = 'GroupExtends'
/// status = 'active'
/// description = 'Example demonstrating a group that extends another group to inherit its rules'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group Base(source src : Patient, target tgt : Patient) {
  src.id as v -> tgt.id = v;
}

group GroupExtends(source src : Patient, target tgt : Patient) extends Base {
  src.active as v -> tgt.active = v;
}

Group - Types

example: group-types.fml

The <<types>> stereotype marks a group as the default mapping for a source/target type pair.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/GroupTypes'
/// name = 'GroupTypes'
/// status = 'active'
/// description = 'Example demonstrating the types stereotype marking a default mapping for a type pair'

uses "http://hl7.org/fhir/StructureDefinition/HumanName" as source
uses "http://hl7.org/fhir/StructureDefinition/HumanName" as target

group GroupTypes(source src : HumanName, target tgt : HumanName) <<types>> {
  src.family as v -> tgt.family = v;
  src.text as v -> tgt.text = v;
}

Group - Type Plus

example: group-type-plus.fml

The <<type+>> stereotype is like <<types>> but also creates the target type when not fixed.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/GroupTypePlus'
/// name = 'GroupTypePlus'
/// status = 'active'
/// description = 'Example demonstrating the type+ stereotype that also creates the target type when not fixed'

uses "http://hl7.org/fhir/StructureDefinition/Identifier" as source
uses "http://hl7.org/fhir/StructureDefinition/Identifier" as target

group GroupTypePlus(source src : Identifier, target tgt : Identifier) <<type+>> {
  src.system as v -> tgt.system = v;
  src.value as v -> tgt.value = v;
}

Simple

Simple - Identity Transform

example: simple-identity.fml

When source and target types match, the short form src.element -> tgt.element invokes the default mapping.

Note that this is similar to the Source - Simple Copy (below)

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/SimpleIdentity'
/// name = 'SimpleIdentity'
/// status = 'active'
/// description = 'Example demonstrating the identity transform shorthand src.element -> tgt.element'

uses "http://hl7.org/fhir/StructureDefinition/Basic" as source
uses "http://hl7.org/fhir/StructureDefinition/Basic" as target

group SimpleIdentity(source src : Basic, target tgt : Basic) {
  src.id -> tgt.id;
}

Simple - Batch Identity

example: simple-batch.fml

The batch short form copies multiple elements in a single declaration.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/SimpleBatch'
/// name = 'SimpleBatch'
/// status = 'active'
/// description = 'Example demonstrating the batch identity shorthand for copying multiple simple elements in a single rule'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group SimpleBatch(source src : Patient, target tgt : Patient) {
  src -> tgt: id, active, gender;
  src -> tgt: maritalStatus, birthDate "Others";
}

Source

Source - Simple Copy

example: source-copy.fml

Copies a source element to a target element using a named variable.

Note that this is very similar to the Simple - Identity Transform (above)

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/SourceCopy'
/// name = 'SourceCopy'
/// status = 'active'
/// description = 'Example demonstrating a simple copy of a source element to a target element'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group SourceCopy(source src : Patient, target tgt : Patient) {
  // copies src.active to tgt.active via variable 'v'
  src.active as v -> tgt.active = v;
}

Source - Type Filter

example: source-type-filter.fml

A source can be filtered by type using the : type syntax, selecting only matching elements.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/SourceTypeFilter'
/// name = 'SourceTypeFilter'
/// status = 'active'
/// description = 'Example demonstrating source type filtering with the : type syntax'

uses "http://hl7.org/fhir/StructureDefinition/Observation" as source
uses "http://hl7.org/fhir/StructureDefinition/Observation" as target

group SourceTypeFilter(source src : Observation, target tgt : Observation) {
  // only matches when value is a Quantity
  src.value : Quantity as v -> tgt.value = v "vQuant";
}

Source - Cardinality

example: source-cardinality.fml

Specifying min..max on a source raises an error if the actual cardinality is outside the range.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/SourceCardinality'
/// name = 'SourceCardinality'
/// status = 'active'
/// description = 'Example demonstrating cardinality constraints on source elements'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group SourceCardinality(source src : Patient, target tgt : Patient) {
  // error if src has zero or more than one id
  src.id 1..1 as v -> tgt.id = v "r1";
}

Source - Default Value

example: source-default.fml

The default keyword provides a fallback value when the source element is absent.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/SourceDefault'
/// name = 'SourceDefault'
/// status = 'active'
/// description = 'Example demonstrating the default keyword for fallback values'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group SourceDefault(source src : Patient, target tgt : Patient) {
  // if src.active is missing, defaults to true
  src.active default (true) as v -> tgt.active = v;
  src.gender default ('unknown') as v -> tgt.gender = v "defaultCode";
}

Source - List First

example: source-list-first.fml

The first list option selects only the first element from a repeating source.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/SourceListFirst'
/// name = 'SourceListFirst'
/// status = 'active'
/// description = 'Example demonstrating the first list option to select only the first element'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group SourceListFirst(source src : Patient, target tgt : Patient) {
  src.name first as v -> tgt.name as t then {
    v.family as f -> t.family = f "r1";
  } "r2";
}

Source - List Last

example: source-list-last.fml

The last list option selects only the last element from a repeating source.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/SourceListLast'
/// name = 'SourceListLast'
/// status = 'active'
/// description = 'Example demonstrating the last list option to select only the last element'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group SourceListLast(source src : Patient, target tgt : Patient) {
  src.name last as v -> tgt.name as t then {
    v.family as f -> t.family = f "r1";
  } "r2";
}

Source - List Not First

example: source-list-not-first.fml

The not_first list option skips the first element and processes all remaining.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/SourceListNotFirst'
/// name = 'SourceListNotFirst'
/// status = 'active'
/// description = 'Example demonstrating the not_first list option to skip the first element'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group SourceListNotFirst(source src : Patient, target tgt : Patient) {
  src.name not_first as v -> tgt.name as t then {
    v.family as f -> t.family = f "r1";
  } "r2";
}

Source - List Not Last

example: source-list-not-last.fml

The not_last list option processes all elements except the last one.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/SourceListNotLast'
/// name = 'SourceListNotLast'
/// status = 'active'
/// description = 'Example demonstrating the not_last list option to skip the last element'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group SourceListNotLast(source src : Patient, target tgt : Patient) {
  src.name not_last as v -> tgt.name as t then {
    v.family as f -> t.family = f "r1";
  } "r2";
}

Source - List Only One

example: source-list-only-one.fml

The only_one list option raises an error if the source contains more than one element.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/SourceListOnlyOne'
/// name = 'SourceListOnlyOne'
/// status = 'active'
/// description = 'Example demonstrating the only_one list option that errors on multiple elements'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group SourceListOnlyOne(source src : Patient, target tgt : Patient) {
  src.name only_one as v -> tgt.name as t then {
    v.family as f -> t.family = f "r1";
  } "r2";
}

Source - Where Condition

example: source-where.fml

The where clause filters source elements using a FHIRPath expression; non-matching elements are skipped.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/SourceWhere'
/// name = 'SourceWhere'
/// status = 'active'
/// description = 'Example demonstrating the where clause for filtering source elements with FHIRPath'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group SourceWhere(source src : Patient, target tgt : Patient) {
  // only copy names where use is 'official'
  src.name as v where (v.use = 'official') -> tgt.name as t then {
    v.family as f -> t.family = f "r1";
  } "r2";
}

Source - Check Condition

example: source-check.fml

The check clause raises an error if the FHIRPath expression returns false for a matched source.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/SourceCheck'
/// name = 'SourceCheck'
/// status = 'active'
/// description = 'Example demonstrating the check clause that raises an error on failed conditions'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group SourceCheck(source src : Patient, target tgt : Patient) {
  // error if id is longer than 64 characters
  src.id as v check (v.length() <= 64) -> tgt.id = v "r1";
}

Source - Log Statement

example: source-log.fml

The log statement writes a FHIRPath expression result to the application log.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/SourceLog'
/// name = 'SourceLog'
/// status = 'active'
/// description = 'Example demonstrating the log statement for writing to the application log'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group SourceLog(source src : Patient, target tgt : Patient) {
  src.id as v log ('Processing patient id: ' & v) -> tgt.id = v "r1";
}

Source - Multiple Sources

example: source-multiple.fml

Multiple source statements produce a cross-product; the rule fires for each combination.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/SourceMultiple'
/// name = 'SourceMultiple'
/// status = 'active'
/// description = 'Example demonstrating multiple source statements producing a cross-product'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group SourceMultiple(source src : Patient, target tgt : Patient) {
  // fires for each combination of name and identifier
  src.name as n, src.identifier as id -> tgt.name as tn then {
    n.family as f -> tn.family = f "r1";
  } "r2";
}

Target

Target - List Modes

example: target-list-modes.fml

Target list modes (first, last, share, single) control how repeating target elements are managed.

<p>Error processing command: Unable to find fragment resource StructureMap/TargetListModes pointed to in file /scratch/repo/input/pagecontent/examples

Target - Multiple Targets

example: target-multiple.fml

A single rule can produce multiple target assignments separated by commas.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/TargetMultiple'
/// name = 'TargetMultiple'
/// status = 'active'
/// description = 'Example demonstrating multiple target assignments in a single rule'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group TargetMultiple(source src : Patient, target tgt : Patient) {
  // set both id and active in a single rule
  src.id as v -> tgt.id = v, tgt.active = true "r1";
}

Target - Sub-Element

example: target-subelement.fml

Target elements can be qualified with sub-elements using dot notation.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/TargetSubelement'
/// name = 'TargetSubelement'
/// status = 'active'
/// description = 'Example demonstrating target sub-element access using dot notation'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group TargetSubelement(source src : Patient, target tgt : Patient) {
  // directly access sub-element without intermediate variable
  src.name as v -> tgt.name as tn then {
    v.family as f -> tn.family = f "r1";
  } "r2";
  src.contact as c, c.name as cn -> tgt.contact as tc, tc.name as tn then {
    cn.family as f -> tn.family = f "r3";
  } "r4";
}

Target - Using FHIRPath as a source

example: fhirpath-source-as-var.fml

Although you can't currently use a fhirpath expression as a source directly, there is a workaround where you can use the target side to create a variable and populate it with a fhirpath expression, then use that value in a then dependent set of rules.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/FhirPathSourceAsVar'
/// name = 'FhirPathSourceAsVar'
/// status = 'active'
/// description = 'Example demonstrating the where clause for filtering source elements with FHIRPath'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group FhirPathSourceAsVar(source src : Patient, target tgt : Patient) {
  // trigger on src, and stash a constant
  src -> ('http://example.org/') as extBase then {
    // use the stashed constant as a variable in a where clause to filter source elements
    src.name as sn -> tgt.name as tn then {
      sn.family as f -> tn.family = f, tn.extension as e, e.url = (extBase & 'family'), e.value = f "r1";
      sn.suffix as f -> tn.suffix = f, tn.extension as e, e.url = (extBase & 'suffix'), e.value = f "r1";
    } "r2";
  } "r3";
}

Transform

Transform - create

example: transform-create.fml

The create transform constructs a new instance of a specified type.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/TransformCreate'
/// name = 'TransformCreate'
/// status = 'active'
/// description = 'Example demonstrating the create transform to construct a new typed instance'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Person" as target

group TransformCreate(source src : Patient, target tgt : Person) {
  src.name as v -> tgt.name = create('HumanName') as tn then {
    v.family as f -> tn.family = f "r1";
  } "r2";
}

Transform - truncate

example: transform-truncate.fml

The truncate transform limits a string to a specified maximum length.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/TransformTruncate'
/// name = 'TransformTruncate'
/// status = 'active'
/// description = 'Example demonstrating the truncate transform to limit string length'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group TransformTruncate(source src : Patient, target tgt : Patient) {
  // truncate the id to 20 characters
  src.id as v -> tgt.id = truncate(v, 20) "r1";
}

Transform - cast

example: transform-cast.fml

The cast transform converts a value from one type to another.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/TransformCast'
/// name = 'TransformCast'
/// status = 'active'
/// description = 'Example demonstrating the cast transform for type conversion'

uses "http://hl7.org/fhir/StructureDefinition/Basic" as source
uses "http://hl7.org/fhir/StructureDefinition/Basic" as target

group TransformCast(source src : Basic, target tgt : Basic) {
  src.id as v -> tgt.id = cast(v, 'string') "r1";
}

Transform - append

example: transform-append.fml

The append transform concatenates multiple string values together.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/TransformAppend'
/// name = 'TransformAppend'
/// status = 'active'
/// description = 'Example demonstrating the append transform to concatenate string values'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group TransformAppend(source src : Patient, target tgt : Patient) {
  src.name as v -> tgt.name as tn then {
    v.family as f, v.text as t -> tn.text = append(f, ' ', t) "r1";
  } "r2";
}

Transform - translate

example: transform-translate.fml

The translate transform maps codes using a ConceptMap via the $translate operation.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/TransformTranslate'
/// name = 'TransformTranslate'
/// status = 'active'
/// description = 'Example demonstrating the translate transform using a ConceptMap for code mapping'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group TransformTranslate(source src : Patient, target tgt : Patient) {
  src.gender as v -> tgt.gender = translate(v, 'http://example.org/ConceptMap/gender-map', 'code') "r1";
}

Transform - reference

example: transform-reference.fml

The reference transform produces a reference string pointing to the specified resource.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/TransformReference'
/// name = 'TransformReference'
/// status = 'active'
/// description = 'Example demonstrating the reference transform to generate a resource reference'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Bundle" as target
uses "http://hl7.org/fhir/StructureDefinition/Encounter" as produced

group TransformReference(source src : Patient, target tgt : Bundle) {
  src -> create('Encounter') as enc, tgt.entry as entry then {
    src -> entry.resource = enc "r1";
    src.id as v -> enc.subject = reference(src) "r2";
  } "referenceTest";
}

Transform - evaluate

example: transform-evaluate.fml

The evaluate transform executes a FHIRPath expression and uses the result as the target value.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/TransformEvaluate'
/// name = 'TransformEvaluate'
/// status = 'active'
/// description = 'Example demonstrating the evaluate transform to execute a FHIRPath expression'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group TransformEvaluate(source src : Patient, target tgt : Patient) {
  src.name as v -> tgt.name as tn then {
    // Replace the individual properties into text using FHIRPath
    v -> tn.text = evaluate(v, surname + ', ' & given.join(' ')) "r2";
  } "r1";
}

Transform - cc

example: transform-cc.fml

The cc transform creates a CodeableConcept from system, code, and optional display parameters.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/TransformCc'
/// name = 'TransformCc'
/// status = 'active'
/// description = 'Example demonstrating the cc transform to create a CodeableConcept'

uses "http://hl7.org/fhir/StructureDefinition/Basic" as source
uses "http://hl7.org/fhir/StructureDefinition/Basic" as target

group TransformCc(source src : Basic, target tgt : Basic) {
  src -> tgt.code = cc('http://example.org/cs', 'example', 'Example Code') "r1";
}

Transform - c

example: transform-c.fml

The c transform creates a Coding from system, code, and optional display parameters.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/TransformC'
/// name = 'TransformC'
/// status = 'active'
/// description = 'Example demonstrating the c transform to create a Coding'

uses "http://hl7.org/fhir/StructureDefinition/Basic" as source
uses "http://hl7.org/fhir/StructureDefinition/Basic" as target

group TransformC(source src : Basic, target tgt : Basic) {
  src -> tgt.code as cc then {
    src -> cc.coding = c('http://example.org/cs', 'test', 'Test Coding') "r1";
  } "r2";
}

Transform - qty

example: transform-qty.fml

The qty transform creates a Quantity from value, unit, and optional system/code.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/TransformQty'
/// name = 'TransformQty'
/// status = 'active'
/// description = 'Example demonstrating the qty transform to create a Quantity'

uses "http://hl7.org/fhir/StructureDefinition/Observation" as source
uses "http://hl7.org/fhir/StructureDefinition/Observation" as target

group TransformQty(source src : Observation, target tgt : Observation) {
  src -> tgt.value = qty(42, 'kg', 'http://unitsofmeasure.org', 'kg') "r1";
}

Transform - id

example: transform-id.fml

The id transform creates an Identifier from system, value, and optional type.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/TransformId'
/// name = 'TransformId'
/// status = 'active'
/// description = 'Example demonstrating the id transform to create an Identifier'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group TransformId(source src : Patient, target tgt : Patient) {
  src -> tgt.identifier = id('http://example.org/ids', '12345') "r1";
}

Transform - cp

example: transform-cp.fml

The cp transform creates a ContactPoint from system and value.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/TransformCp'
/// name = 'TransformCp'
/// status = 'active'
/// description = 'Example demonstrating the cp transform to create a ContactPoint'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group TransformCp(source src : Patient, target tgt : Patient) {
  src -> tgt.telecom = cp('phone', '555-0100') "r1";
}

Transform - uuid

example: transform-uuid.fml

The uuid transform generates a random UUID.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/TransformUuid'
/// name = 'TransformUuid'
/// status = 'active'
/// description = 'Example demonstrating the uuid transform to generate a unique identifier'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group TransformUuid(source src : Patient, target tgt : Patient) {
  src -> tgt.id = uuid() "r1";
}

Dependent

Dependent - Inline Rules

example: dependent-inline.fml

Rules can contain inline dependent rules in a then { } block.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/DependentInline'
/// name = 'DependentInline'
/// status = 'active'
/// description = 'Example demonstrating inline dependent rules in a then { } block'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group DependentInline(source src : Patient, target tgt : Patient) {
  src.name as sn -> tgt.name as tn then {
    sn.family as f -> tn.family = f "r1";
    sn.given as g -> tn.given = g "r2";
  } "r3";
}

Dependent - Group Invocation

example: dependent-group.fml

A rule can invoke another group by name using then GroupName(params).

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/DependentGroup'
/// name = 'DependentGroup'
/// status = 'active'
/// description = 'Example demonstrating invoking another group by name using then GroupName(params)'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target
uses "http://hl7.org/fhir/StructureDefinition/HumanName" as source
uses "http://hl7.org/fhir/StructureDefinition/HumanName" as target

group DependentGroup(source src : Patient, target tgt : Patient) {
  src.name as sn -> tgt.name as tn then CopyName(sn, tn) "r1";
}

group CopyName(source src : HumanName, target tgt : HumanName) {
  src.family as v -> tgt.family = v;
  src.given as v -> tgt.given = v;
}

Dependent - Multiple Groups

example: dependent-multi-group.fml

A rule can invoke multiple groups in sequence, separated by commas.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/DependentMultiGroup'
/// name = 'DependentMultiGroup'
/// status = 'active'
/// description = 'Example demonstrating invoking multiple groups in sequence separated by commas'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target
uses "http://hl7.org/fhir/StructureDefinition/HumanName" as source
uses "http://hl7.org/fhir/StructureDefinition/HumanName" as target

group DependentMultiGroup(source src : Patient, target tgt : Patient) {
  src.name as sn -> tgt.name as tn then CopyFamily(sn, tn), CopyGiven(sn, tn) "r1";
}

group CopyFamily(source src : HumanName, target tgt : HumanName) {
  src.family as v -> tgt.family = v;
}

group CopyGiven(source src : HumanName, target tgt : HumanName) {
  src.given as v -> tgt.given = v;
}

Structure

Structure - Property to Array

example: struct-prop-to-array.fml

Maps a scalar property into a repeating array element by wrapping it in a new structure.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/StructPropToArray'
/// name = 'StructPropToArray'
/// status = 'active'
/// description = 'Example demonstrating mapping a scalar property into a repeating array element'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group StructPropToArray(source src : Patient, target tgt : Patient) {
  // map scalar id into a repeating identifier element
  src.id as v -> tgt.identifier as ident then {
    v -> ident.value = v "r1";
    v -> ident.system = 'http://example.org/ids' "r2";
  } "r3";
}

Structure - Array to Property

example: struct-array-to-prop.fml

Extracts a single value from a repeating array using first or last and maps it to a scalar property.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/StructArrayToProp'
/// name = 'StructArrayToProp'
/// status = 'active'
/// description = 'Example demonstrating extracting a single value from an array into a scalar property'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group StructArrayToProp(source src : Patient, target tgt : Patient) {
  // take the first name's family and put it into the scalar id
  src.name first as v then {
    v.family as f -> tgt.id = f "r1";
  } "r2";
}

Structure - Array to Array

example: struct-array-to-array.fml

Maps each element of a repeating source array to a corresponding element in a repeating target array.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/StructArrayToArray'
/// name = 'StructArrayToArray'
/// status = 'active'
/// description = 'Example demonstrating mapping a repeating source array to a repeating target array'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group StructArrayToArray(source src : Patient, target tgt : Patient) {
  // one target name created for each source name
  src.name as sn -> tgt.name as tn then {
    sn.family as f -> tn.family = f "r1";
    sn.given as g -> tn.given = g "r2";
    sn.use as u -> tn.use = u "r3";
  } "r4";
}

Structure - Nested to Top Level

example: struct-nested-to-top.fml

Pulls a value from a nested child element up to a top-level property.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/StructNestedToTop'
/// name = 'StructNestedToTop'
/// status = 'active'
/// description = 'Example demonstrating pulling a nested child element up to a top-level property'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group StructNestedToTop(source src : Patient, target tgt : Patient) {
  // pull nested contact.name.family up into top-level id
  src.contact as c then {
    c.name as cn then {
      cn.family as f -> tgt.id = f "r1";
    } "r2";
  } "r3";
}

Structure - Top Level to Nested

example: struct-top-to-nested.fml

Pushes a top-level property value down into a nested structure.

/// url = 'http://hl7.org/fhir/uv/fml/StructureMap/StructTopToNested'
/// name = 'StructTopToNested'
/// status = 'active'
/// description = 'Example demonstrating pushing a top-level property down into a nested structure'

uses "http://hl7.org/fhir/StructureDefinition/Patient" as source
uses "http://hl7.org/fhir/StructureDefinition/Patient" as target

group StructTopToNested(source src : Patient, target tgt : Patient) {
  // push top-level id down into name.text
  src.id as v -> tgt.name as tn then {
    v -> tn.text = v "r1";
    v -> tn.use = 'temp' "r2";
  } "r3";
}