Clarotech.OpenEHR.RM.Flat 1.0.0

dotnet add package Clarotech.OpenEHR.RM.Flat --version 1.0.0
                    
NuGet\Install-Package Clarotech.OpenEHR.RM.Flat -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Clarotech.OpenEHR.RM.Flat" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Clarotech.OpenEHR.RM.Flat" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Clarotech.OpenEHR.RM.Flat" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Clarotech.OpenEHR.RM.Flat --version 1.0.0
                    
#r "nuget: Clarotech.OpenEHR.RM.Flat, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Clarotech.OpenEHR.RM.Flat@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Clarotech.OpenEHR.RM.Flat&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Clarotech.OpenEHR.RM.Flat&version=1.0.0
                    
Install as a Cake Tool

Clarotech.OpenEHR.RM.Flat

openEHR "FLAT" (web template) JSON encoding and decoding for the openEHR Reference Model, built on System.Text.Json.

FLAT JSON is the flattened path/value format popularised by Marand/Better and reimplemented by EHRbase's openEHR_SDK — the de facto interop target most openEHR tooling expects. Instead of nested canonical JSON, a composition is represented as a flat map of "path|suffix": value pairs, e.g.:

{
  "vaccination_management/vaccine_code|code": "38598009",
  "vaccination_management/vaccine_code|terminology": "SNOMED-CT",
  "vaccination_management/vaccine_code|value": "Diphtheria vaccine",
  "vaccination_management/medication_details/expiration_date": "2026-01-01T00:00:00Z"
}

This package does not parse OPT templates or generate flat paths from an archetype — it provides the low-level building blocks (FlatPath, FlatValueCodec, FlatJsonSerializer) that a code generator or hand-written mapping layer uses to read and write these paths against openEHR RM data values.

NuGet CI License

Contents


Installation

dotnet add package Clarotech.OpenEHR.RM.Flat

Targets net8.0 and net10.0.


API overview

using Clarotech.OpenEHR.RM.Flat;
Member Description
FlatPath.BuildId(termText) Slugifies a human-readable term (e.g. archetype term text) into a flat-path id segment
FlatPath.Segment(id, occurrenceIndex) Formats an id with an optional :N occurrence suffix
FlatPath.Join(segments) Joins path segments with /, skipping null/empty ones
FlatValueCodec.Write(target, basePath, value) Writes one RM data value's flat key(s) into a IDictionary<string, object?>
FlatValueCodec.Read*(source, basePath) Reads one RM data value back out of a flat map, tolerating missing/partial keys
FlatJsonSerializer.Serialize(flatMap) Serializes a flat map to a JSON string
FlatJsonSerializer.Deserialize(json) Parses a flat JSON string back into a Dictionary<string, object?>

FlatPath — id and path construction

FlatPath.BuildId("Serum sodium");        // "serum_sodium"
FlatPath.BuildId("2nd vaccination");      // "a2nd_vaccination"  (digit-prefixed ids get an 'a' prefix)

FlatPath.Segment("participation");        // "participation"       (no index)
FlatPath.Segment("participation", 0);     // "participation:0"

FlatPath.Join("vaccination_management", "vaccine_code"); // "vaccination_management/vaccine_code"
FlatPath.Join("", "vaccine_code");                        // "vaccine_code"  (empty segments are skipped)

BuildId follows the same id-derivation algorithm as EHRbase's OPTParser.buildId: strip non-alphanumeric characters to spaces, collapse whitespace to _, lowercase, and prefix with a if the result starts with a digit. Sibling disambiguation (appending 2, 3, ... to a repeated base id) is the caller's responsibility, since it depends on the caller's own notion of "siblings" (e.g. a code generator's property list for one class) — this package only slugifies a single term at a time.


FlatValueCodec — per-type suffix keys

Each RM leaf data type has a fixed, hardcoded set of flat-key suffixes, matching the suffix rules found in EHRbase's openEHR_SDK (serialisation/flatencoding/std/marshal/config/*.java):

RM type Keys
DvText bare → Value; \|formatting → Formatting
DvCodedText \|code, \|terminology, \|value, \|formatting
DvOrdinal \|code, \|value (from the symbol), \|ordinal (the int)
DvQuantity \|magnitude, \|precision, \|unit, \|units_system, \|units_display_name
DvCount bare → integer magnitude
DvBoolean bare
DvProportion \|numerator, \|denominator, \|type, \|precision, bare → magnitude
DvIdentifier \|id, \|issuer, \|assigner, \|type
DvDateTime / DvDate / DvTime / DvDuration bare → ISO 8601 string
DvUri / DvEhrUri bare
DvParsable bare (or \|value), \|formalism
DvMultimedia \|value, \|mediatype, \|compression_algorithm, \|integrity_check_algorithm, \|integrity_check, \|data, \|size, \|alternatetext

Write is a no-op when passed a null value. Read* returns null when none of a type's relevant keys are present under the given path; otherwise it returns a partially-populated instance using whichever subset of keys exist (missing individual keys are simply left unset — never an error).

var map = new Dictionary<string, object?>();
FlatValueCodec.Write(map, "vaccine_code", new DvCodedText(
    "Diphtheria vaccine",
    new CodePhrase(new TerminologyId("SNOMED-CT"), "38598009")));
// map["vaccine_code|code"]        == "38598009"
// map["vaccine_code|terminology"] == "SNOMED-CT"
// map["vaccine_code|value"]       == "Diphtheria vaccine"

DvCodedText? restored = FlatValueCodec.ReadDvCodedText(map, "vaccine_code");

FlatJsonSerializer

string json = FlatJsonSerializer.Serialize(map, indented: true);
Dictionary<string, object?> restored = FlatJsonSerializer.Deserialize(json);

Backed by System.Text.Json. Deserialize uses an inferred-type object converter so values come back as real bool/double/long/string, not raw JsonElement.


Worked example

using Clarotech.OpenEHR.RM.Flat;
using OpenEHR.RM.DataTypes.Text;
using OpenEHR.RM.DataTypes.DateTime;

var map = new Dictionary<string, object?>();

FlatValueCodec.Write(map, FlatPath.Join("vaccination_management", "vaccine_code"),
    new DvCodedText("Diphtheria vaccine", new CodePhrase(new TerminologyId("SNOMED-CT"), "38598009")));

FlatValueCodec.Write(map, FlatPath.Join("vaccination_management", "medication_details", "expiration_date"),
    new DvDateTime("2026-01-01T00:00:00Z"));

string json = FlatJsonSerializer.Serialize(map, indented: true);

Supported RM types

DvText, DvCodedText, DvOrdinal, DvQuantity, DvCount, DvBoolean, DvProportion, DvIdentifier, DvDateTime, DvDate, DvTime, DvDuration, DvUri, DvEhrUri, DvParsable, DvMultimedia.


Dependencies


License

Apache-2.0 — see LICENSE.txt

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 135 7/12/2026