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
<PackageReference Include="Clarotech.OpenEHR.RM.Flat" Version="1.0.0" />
<PackageVersion Include="Clarotech.OpenEHR.RM.Flat" Version="1.0.0" />
<PackageReference Include="Clarotech.OpenEHR.RM.Flat" />
paket add Clarotech.OpenEHR.RM.Flat --version 1.0.0
#r "nuget: Clarotech.OpenEHR.RM.Flat, 1.0.0"
#:package Clarotech.OpenEHR.RM.Flat@1.0.0
#addin nuget:?package=Clarotech.OpenEHR.RM.Flat&version=1.0.0
#tool nuget:?package=Clarotech.OpenEHR.RM.Flat&version=1.0.0
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.
Contents
- Installation
- API overview
FlatPath— id and path constructionFlatValueCodec— per-type suffix keysFlatJsonSerializer- Worked example
- Supported RM types
- Dependencies
- License
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
Clarotech.OpenEHR.RM— openEHR Reference Model classes
License
Apache-2.0 — see LICENSE.txt
| Product | Versions 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. |
-
net10.0
- Clarotech.OpenEHR.RM (>= 1.0.0)
-
net8.0
- Clarotech.OpenEHR.RM (>= 1.0.0)
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 |