Canonical JSON serialization and deserialization for the openEHR Reference Model using System.Text.Json.
Faithfully implements the openEHR canonical JSON format: _type discriminator written first on every object, snake_case property names, optional properties omitted when null. Covers every concrete RM type in the openEHR RM 1.1.0 specification — compositions, data types, data structures, EHR records, and versioning.
- Installation
- API overview
- Serialization
- Deserialization
- Using
OpenEhrJsonOptions.Defaultdirectly - Worked examples
- Integrations
- Supported RM types
- Dependencies
- License
dotnet add package Clarotech.OpenEHR.RM.JsonTargets net8.0 and net10.0.
using Clarotech.OpenEHR.RM.Json;| Member | Description |
|---|---|
OpenEhrJsonSerializer.Serialize<T>(value) |
Serialize to canonical JSON string (compact) |
OpenEhrJsonSerializer.Serialize<T>(value, writeIndented: true) |
Serialize to canonical JSON string (pretty-printed) |
OpenEhrJsonSerializer.SerializeByRuntimeType(value) |
Serialize using the object's runtime type — use when the declared type is abstract |
OpenEhrJsonSerializer.Deserialize<T>(json) |
Deserialize from a JSON string |
OpenEhrJsonSerializer.Deserialize<T>(stream) |
Deserialize synchronously from a UTF-8 stream |
OpenEhrJsonSerializer.DeserializeAsync<T>(stream, ct) |
Deserialize asynchronously from a UTF-8 stream |
OpenEhrJsonOptions.Default |
The pre-configured JsonSerializerOptions — use directly in ASP.NET, HttpClient, etc. |
string json = OpenEhrJsonSerializer.Serialize(composition);
// {"_type":"COMPOSITION","archetype_node_id":"openEHR-EHR-COMPOSITION.encounter.v1",...}string json = OpenEhrJsonSerializer.Serialize(composition, writeIndented: true);
// {
// "_type": "COMPOSITION",
// "archetype_node_id": "openEHR-EHR-COMPOSITION.encounter.v1",
// ...
// }When your variable is declared as a base type (e.g. DataValue, ContentItem, ItemStructure), use SerializeByRuntimeType to ensure the correct _type discriminator is written:
DataValue value = new DvQuantity(72.5, "kg");
// Wrong: serialises as DataValue — no _type written
string bad = OpenEhrJsonSerializer.Serialize(value);
// Correct: uses DvQuantity's runtime type
string good = OpenEhrJsonSerializer.SerializeByRuntimeType(value);
// {"_type":"DV_QUANTITY","magnitude":72.5,"units":"kg"}Composition? comp = OpenEhrJsonSerializer.Deserialize<Composition>(json);The _type discriminator in the JSON drives dispatch — you can deserialize any subtype through the base:
string json = """{"_type":"DV_CODED_TEXT","value":"Blood pressure","defining_code":{...}}""";
DataValue? dv = OpenEhrJsonSerializer.Deserialize<DataValue>(json);
// dv is DvCodedText at runtimeusing var stream = File.OpenRead("composition.json");
Composition? comp = OpenEhrJsonSerializer.Deserialize<Composition>(stream);using var stream = File.OpenRead("composition.json");
Composition? comp = await OpenEhrJsonSerializer.DeserializeAsync<Composition>(stream, cancellationToken);OpenEhrJsonOptions.Default is a pre-configured, shared JsonSerializerOptions instance.
Use it wherever the framework expects options — no need to create converters manually.
JsonSerializerOptions opts = OpenEhrJsonOptions.Default;
// Plain System.Text.Json calls
string json = JsonSerializer.Serialize(composition, opts);
Composition? comp = JsonSerializer.Deserialize<Composition>(json, opts);Build a minimal COMPOSITION and serialize it:
using OpenEHR.RM.Composition;
using OpenEHR.RM.DataTypes.Text;
using OpenEHR.RM.DataTypes.Basic;
using OpenEHR.RM.Common.Generic;
var composition = new Composition
{
ArchetypeNodeId = "openEHR-EHR-COMPOSITION.encounter.v1",
Name = new DvText("Encounter"),
Language = new CodePhrase(new TerminologyId("ISO_639-1"), "en"),
Territory = new CodePhrase(new TerminologyId("ISO_3166-1"), "GB"),
Category = new DvCodedText("event", new CodePhrase(new TerminologyId("openehr"), "433")),
Composer = new PartySelf(),
ArchetypeDetails = new Archetyped
{
ArchetypeId = new ArchetypeId("openEHR-EHR-COMPOSITION.encounter.v1"),
RmVersion = "1.1.0",
TemplateId = new TemplateId("Encounter")
}
};
string json = OpenEhrJsonSerializer.Serialize(composition, writeIndented: true);Output:
{
"_type": "COMPOSITION",
"archetype_node_id": "openEHR-EHR-COMPOSITION.encounter.v1",
"name": {
"_type": "DV_TEXT",
"value": "Encounter"
},
"archetype_details": {
"_type": "ARCHETYPED",
"archetype_id": { "_type": "ARCHETYPE_ID", "value": "openEHR-EHR-COMPOSITION.encounter.v1" },
"template_id": { "_type": "TEMPLATE_ID", "value": "Encounter" },
"rm_version": "1.1.0"
},
"language": { "_type": "CODE_PHRASE", "terminology_id": { "_type": "TERMINOLOGY_ID", "value": "ISO_639-1" }, "code_string": "en" },
"territory": { "_type": "CODE_PHRASE", "terminology_id": { "_type": "TERMINOLOGY_ID", "value": "ISO_3166-1" }, "code_string": "GB" },
"category": {
"_type": "DV_CODED_TEXT",
"value": "event",
"defining_code": { "_type": "CODE_PHRASE", "terminology_id": { "_type": "TERMINOLOGY_ID", "value": "openehr" }, "code_string": "433" }
},
"composer": { "_type": "PARTY_SELF" }
}Round-trip:
Composition? restored = OpenEhrJsonSerializer.Deserialize<Composition>(json);
Console.WriteLine(restored!.Language.CodeString); // "en"
Console.WriteLine(restored.Composer is PartySelf); // truevar plain = new DvText("Blood pressure");
// {"_type":"DV_TEXT","value":"Blood pressure"}
var coded = new DvCodedText(
"Blood pressure",
new CodePhrase(new TerminologyId("LOINC"), "55284-4"));
// {"_type":"DV_CODED_TEXT","value":"Blood pressure","defining_code":{...}}
// DvText with hyperlink formatting
var linked = new DvText("See guidelines", formatting: "plain", hyperlink: new DvUri("https://example.com"));
// {"_type":"DV_TEXT","value":"See guidelines","formatting":"plain","hyperlink":{"_type":"DV_URI","value":"https://example.com"}}var qty = new DvQuantity(72.5, "kg");
// {"_type":"DV_QUANTITY","magnitude":72.5,"units":"kg"}
// With precision and units system
var detailed = new DvQuantity(
magnitude: 36.6,
units: "Cel",
precision: 1,
unitsSystem: "UCUM",
unitsDisplayName: "°C");
// {"_type":"DV_QUANTITY","magnitude":36.6,"units":"Cel","precision":1,"units_system":"UCUM","units_display_name":"°C"}
// With accuracy
var withAccuracy = new DvQuantity(
magnitude: 120.0,
units: "mm[Hg]",
accuracy: 2.0,
accuracyIsPercent: false);var count = new DvCount(3);
// {"_type":"DV_COUNT","magnitude":3}var ratio = new DvProportion(1.0, 4.0, ProportionKind.Ratio);
// {"_type":"DV_PROPORTION","numerator":1,"denominator":4,"type":0}
var percent = new DvProportion(95.0, 100.0, ProportionKind.Percentage, precision: 1);
// {"_type":"DV_PROPORTION","numerator":95,"denominator":100,"type":2,"precision":1}var ordinal = new DvOrdinal(
2,
new DvCodedText("Moderate", new CodePhrase(new TerminologyId("local"), "at0006")));
// {"_type":"DV_ORDINAL","value":2,"symbol":{"_type":"DV_CODED_TEXT","value":"Moderate",...}}
var scale = new DvScale(
2.5,
new DvCodedText("Mild–moderate", new CodePhrase(new TerminologyId("local"), "at0007")));var flag = new DvBoolean(true);
// {"_type":"DV_BOOLEAN","value":true}var dt = new DvDateTime("2024-11-15T09:30:00Z");
var date = new DvDate("2024-11-15");
var time = new DvTime("09:30:00Z");
// {"_type":"DV_DATE_TIME","value":"2024-11-15T09:30:00Z"}
// {"_type":"DV_DATE","value":"2024-11-15"}
// {"_type":"DV_TIME","value":"09:30:00Z"}var dur = new DvDuration("PT2H30M");
// {"_type":"DV_DURATION","value":"PT2H30M"}var id = new DvIdentifier(
id: "ABC123",
issuer: "NHS",
assigner: "GP Practice",
type: "LOCAL");
// {"_type":"DV_IDENTIFIER","id":"ABC123","issuer":"NHS","assigner":"GP Practice","type":"LOCAL"}var uri = new DvUri("https://example.com/resource");
var ehrUri = new DvEhrUri("ehr://system.example.com/ehr/abc123");var media = new DvMultimedia(
mediaType: new CodePhrase(new TerminologyId("IANA_media-types"), "image/png"),
size: 2048,
uri: new DvUri("https://example.com/image.png"));
// {"_type":"DV_MULTIMEDIA","media_type":{...},"size":2048,"uri":{...}}var parsable = new DvParsable("text/plain", "Some structured text");
// {"_type":"DV_PARSABLE","formalism":"text/plain","value":"Some structured text"}All DvOrdered subtypes support NormalStatus, NormalRange, and OtherReferenceRanges.
// Normal range: systolic blood pressure 90–140 mmHg
var normalRange = new ReferenceRange<DvOrdered>(
range: new DvInterval<DvOrdered>(
lower: new DvQuantity(90, "mm[Hg]"),
upper: new DvQuantity(140, "mm[Hg]"),
lowerUnbounded: false,
upperUnbounded: false,
lowerIncluded: true,
upperIncluded: true),
meaning: new DvText("Normal adult range"));
// Additional reference ranges
var pediatricRange = new ReferenceRange<DvOrdered>(
range: new DvInterval<DvOrdered>(
lower: new DvQuantity(80, "mm[Hg]"),
upper: new DvQuantity(120, "mm[Hg]"),
lowerUnbounded: false,
upperUnbounded: false,
lowerIncluded: true,
upperIncluded: true),
meaning: new DvText("Pediatric range"));
var systolic = new DvQuantity(
magnitude: 125.0,
units: "mm[Hg]",
normalStatus: new CodePhrase(new TerminologyId("openehr_normal_statuses"), "N"),
normalRange: normalRange,
otherReferenceRanges: new[] { pediatricRange });
string json = OpenEhrJsonSerializer.Serialize(systolic, writeIndented: true);
// {
// "_type": "DV_QUANTITY",
// "magnitude": 125,
// "units": "mm[Hg]",
// "normal_status": { "_type": "CODE_PHRASE", ... "code_string": "N" },
// "normal_range": {
// "_type": "REFERENCE_RANGE",
// "meaning": { "_type": "DV_TEXT", "value": "Normal adult range" },
// "range": { "_type": "DV_INTERVAL", "lower": { "_type": "DV_QUANTITY", ... }, ... }
// },
// "other_reference_ranges": [...]
// }
// Deserialize and access the normal range
DvQuantity? restored = OpenEhrJsonSerializer.Deserialize<DvQuantity>(json);
Console.WriteLine(restored!.NormalRange?.Meaning?.Value); // "Normal adult range"
Console.WriteLine(restored.NormalStatus?.CodeString); // "N"DvInterval<T> wraps a bounded range of any DvOrdered subtype.
It always carries lower_included, lower_unbounded, upper_included, upper_unbounded.
// Closed interval: 18–65 years
var ageRange = new DvInterval<DvQuantity>(
lower: new DvQuantity(18, "a"),
upper: new DvQuantity(65, "a"),
lowerUnbounded: false,
upperUnbounded: false,
lowerIncluded: true,
upperIncluded: true);
// Upper-unbounded: ≥ 18
var adultRange = new DvInterval<DvQuantity>(
lower: new DvQuantity(18, "a"),
upper: null,
lowerUnbounded: false,
upperUnbounded: true,
lowerIncluded: true,
upperIncluded: false);
// Interval of date-times (e.g. participation window)
var window = new DvInterval<DvDateTime>(
lower: new DvDateTime("2024-01-01T00:00:00Z"),
upper: new DvDateTime("2024-12-31T23:59:59Z"),
lowerUnbounded: false,
upperUnbounded: false,
lowerIncluded: true,
upperIncluded: true);
string json = OpenEhrJsonSerializer.Serialize(ageRange, writeIndented: true);
// {
// "_type": "DV_INTERVAL",
// "lower": { "_type": "DV_QUANTITY", "magnitude": 18, "units": "a" },
// "lower_included": true,
// "lower_unbounded": false,
// "upper": { "_type": "DV_QUANTITY", "magnitude": 65, "units": "a" },
// "upper_included": true,
// "upper_unbounded": false
// }
DvInterval<DvQuantity>? restored = OpenEhrJsonSerializer.Deserialize<DvInterval<DvQuantity>>(json);
Console.WriteLine(restored!.Lower?.Magnitude); // 18
Console.WriteLine(restored.UpperUnbounded); // falsevar tree = new ItemTree
{
ArchetypeNodeId = "at0001",
Name = new DvText("Tree"),
Items = new List<Item>
{
new Cluster
{
ArchetypeNodeId = "at0002",
Name = new DvText("Blood pressure"),
Items = new List<Item>
{
new Element
{
ArchetypeNodeId = "at0003",
Name = new DvText("Systolic"),
Value = new DvQuantity(125.0, "mm[Hg]")
},
new Element
{
ArchetypeNodeId = "at0004",
Name = new DvText("Diastolic"),
Value = new DvQuantity(82.0, "mm[Hg]")
}
}
},
new Element
{
ArchetypeNodeId = "at0005",
Name = new DvText("Comment"),
Value = new DvText("Patient was resting")
}
}
};
string json = OpenEhrJsonSerializer.Serialize(tree, writeIndented: true);An ELEMENT with no recorded value uses NullFlavour:
var missing = new Element
{
ArchetypeNodeId = "at0006",
Name = new DvText("Body weight"),
NullFlavour = new DvCodedText(
"no information",
new CodePhrase(new TerminologyId("openehr"), "271")),
NullReason = new DvText("Not measured today")
};An ITEM_TABLE represents rows as CLUSTER objects:
var table = new ItemTable
{
ArchetypeNodeId = "at0001",
Name = new DvText("Medications"),
Rows = new List<Cluster>
{
new Cluster
{
ArchetypeNodeId = "at0002",
Name = new DvText("Row 1"),
Items = new List<Item>
{
new Element { ArchetypeNodeId = "at0003", Name = new DvText("Name"), Value = new DvText("Metformin") },
new Element { ArchetypeNodeId = "at0004", Name = new DvText("Dose"), Value = new DvQuantity(500, "mg") }
}
}
}
};
// {"_type":"ITEM_TABLE","archetype_node_id":"at0001","name":{...},"rows":[...]}var history = new History<ItemTree>
{
ArchetypeNodeId = "at0001",
Name = new DvText("History"),
Origin = new DvDateTime("2024-11-15T09:30:00Z"),
Events = new List<Event<ItemTree>>
{
new PointEvent<ItemTree>
{
ArchetypeNodeId = "at0002",
Name = new DvText("Any event"),
Time = new DvDateTime("2024-11-15T09:30:00Z"),
Data = tree
}
}
};
// Note: HISTORY objects do NOT carry a "_type" discriminator in canonical JSON.
// Point events carry "_type":"POINT_EVENT".An INTERVAL_EVENT adds width and math_function:
var intervalEvent = new IntervalEvent<ItemTree>
{
ArchetypeNodeId = "at0002",
Name = new DvText("24-hour mean"),
Time = new DvDateTime("2024-11-15T09:00:00Z"),
Data = tree,
Width = new DvDuration("PT24H"),
MathFunction = new DvCodedText(
"mean",
new CodePhrase(new TerminologyId("openehr"), "146")),
SampleCount = 96
};var observation = new Observation
{
ArchetypeNodeId = "openEHR-EHR-OBSERVATION.blood_pressure.v2",
Name = new DvText("Blood pressure"),
Language = new CodePhrase(new TerminologyId("ISO_639-1"), "en"),
Encoding = new CodePhrase(new TerminologyId("IANA_character-sets"), "UTF-8"),
Subject = new PartySelf(),
Provider = new PartyIdentified(name: "Dr Smith"),
Data = new History<ItemStructure>
{
ArchetypeNodeId = "at0001",
Name = new DvText("History"),
Origin = new DvDateTime("2024-11-15T09:30:00Z"),
Events = new List<Event<ItemStructure>>
{
new PointEvent<ItemStructure>
{
ArchetypeNodeId = "at0002",
Name = new DvText("Any event"),
Time = new DvDateTime("2024-11-15T09:30:00Z"),
Data = tree
}
}
},
Protocol = new ItemTree
{
ArchetypeNodeId = "at0011",
Name = new DvText("Protocol"),
Items = new List<Item>
{
new Element
{
ArchetypeNodeId = "at0013",
Name = new DvText("Cuff size"),
Value = new DvCodedText(
"Adult",
new CodePhrase(new TerminologyId("local"), "at0015"))
}
}
}
};
string json = OpenEhrJsonSerializer.Serialize(observation);
Observation? restored = OpenEhrJsonSerializer.Deserialize<Observation>(json);using OpenEHR.RM.Common.ChangeControl;
using OpenEHR.RM.Common.Generic;
using OpenEHR.RM.Support.Identification;
// Create an OriginalVersion wrapping a Composition
var version = new OriginalVersion<Composition>
{
Uid = new ObjectVersionId("abc123::system.example.com::1"),
Contribution = new ObjectRef
{
Id = new HierObjectId("contrib-uid-001"),
Namespace = "local",
Type = "CONTRIBUTION"
},
CommitAudit = new AuditDetails
{
SystemId = "system.example.com",
Committer = new PartyIdentified(name: "Dr Smith"),
TimeCommitted = new DvDateTime("2024-11-15T09:35:00Z"),
ChangeType = new DvCodedText(
"creation",
new CodePhrase(new TerminologyId("openehr"), "249"))
},
LifecycleState = new DvCodedText(
"complete",
new CodePhrase(new TerminologyId("openehr"), "532")),
Data = composition,
PrecedingVersionUid = null // first version
};
string versionJson = OpenEhrJsonSerializer.Serialize(version, writeIndented: true);
// {
// "_type": "ORIGINAL_VERSION",
// "uid": { "_type": "OBJECT_VERSION_ID", "value": "abc123::system.example.com::1" },
// "contribution": { "_type": "OBJECT_REF", ... },
// "commit_audit": { "_type": "AUDIT_DETAILS", ... },
// "lifecycle_state": { "_type": "DV_CODED_TEXT", ... },
// "data": { "_type": "COMPOSITION", ... }
// }
// A Contribution groups one or more version references
var contribution = new Contribution
{
Uid = new HierObjectId("contrib-uid-001"),
Audit = version.CommitAudit,
Versions = new HashSet<ObjectRef>
{
new ObjectRef
{
Id = new ObjectVersionId("abc123::system.example.com::1"),
Namespace = "local",
Type = "VERSIONED_COMPOSITION"
}
}
};
// Deserialize
OriginalVersion<Composition>? restored =
OpenEhrJsonSerializer.Deserialize<OriginalVersion<Composition>>(versionJson);
Console.WriteLine(restored!.Uid.Value); // "abc123::system.example.com::1"
Console.WriteLine(restored.LifecycleState.DefiningCode.CodeString); // "532"An ImportedVersion wraps a pre-existing OriginalVersion imported from another system:
var imported = new ImportedVersion<Composition>
{
CommitAudit = auditDetails,
Contribution = contributionRef,
Item = version // the wrapped OriginalVersion
};
// {"_type":"IMPORTED_VERSION","contribution":{...},"commit_audit":{...},"item":{...}}using OpenEHR.RM.Ehr;
// EHR_STATUS (a Locatable — carries the modifiability flags and subject)
var ehrStatus = new EhrStatus
{
ArchetypeNodeId = "openEHR-EHR-EHR_STATUS.generic.v1",
Name = new DvText("EHR Status"),
Subject = new PartySelf
{
ExternalRef = new PartyRef
{
Id = new HierObjectId("patient-uuid-001"),
Namespace = "local",
Type = "PERSON"
}
},
IsModifiable = true,
IsQueryable = true,
OtherDetails = new ItemTree
{
ArchetypeNodeId = "at0001",
Name = new DvText("Details"),
Items = new List<Item>
{
new Element
{
ArchetypeNodeId = "at0002",
Name = new DvText("Opt-in flag"),
Value = new DvBoolean(true)
}
}
}
};
string statusJson = OpenEhrJsonSerializer.Serialize(ehrStatus, writeIndented: true);
EhrStatus? restoredStatus = OpenEhrJsonSerializer.Deserialize<EhrStatus>(statusJson);
Console.WriteLine(restoredStatus!.IsModifiable); // true
Console.WriteLine((restoredStatus.Subject.ExternalRef as PartyRef)!.Id.Value); // "patient-uuid-001"
// EHR root record — all composition/contribution fields are OBJECT_REF references
var ehr = new Ehr
{
EhrId = new HierObjectId("ehr-uuid-001"),
SystemId = new HierObjectId("system.example.com"),
EhrStatus = new ObjectRef { Id = new HierObjectId("status-uid"), Namespace = "local", Type = "EHR_STATUS" },
EhrAccess = new ObjectRef { Id = new HierObjectId("access-uid"), Namespace = "local", Type = "EHR_ACCESS" },
TimeCreated = new DvDateTime("2024-01-01T00:00:00Z"),
Compositions = new List<ObjectRef>
{
new ObjectRef { Id = new HierObjectId("comp-uid-001"), Namespace = "local", Type = "VERSIONED_COMPOSITION" }
}
};
string ehrJson = OpenEhrJsonSerializer.Serialize(ehr, writeIndented: true);Every Locatable (compositions, entries, data structures, items) can carry Links and a FeederAudit.
// Links — typed directed references to other RM objects
var link = new Link
{
Meaning = new DvText("has-subject"),
Type = new DvText("PROBLEM"),
Target = new DvEhrUri("ehr://system.example.com/ehr/abc/compositions/xyz")
};
var element = new Element
{
ArchetypeNodeId = "at0001",
Name = new DvText("Problem"),
Value = new DvText("Hypertension"),
Links = new HashSet<Link> { link }
};
// FeederAudit — provenance of data imported from a feeder system
var feederAudit = new FeederAudit
{
OriginatingSystemAudit = new FeederAuditDetails
{
SystemId = "GP-System-v3",
Time = new DvDateTime("2024-11-14T08:00:00Z"),
VersionId = "REV-00123"
},
OriginatingSystemItemIds = new List<DvIdentifier>
{
new DvIdentifier(id: "GP-OBS-9876", issuer: "GP-System-v3", type: "LOCAL")
}
};
var observation = new Observation
{
// ... other fields ...
FeederAudit = feederAudit
};Configure the JSON serializer once at startup so all controllers serialize and deserialize canonical openEHR JSON:
// Program.cs / Startup.cs
builder.Services.AddControllers()
.AddJsonOptions(o =>
{
// Copy all openEHR converters into the ASP.NET JsonSerializerOptions
foreach (var converter in OpenEhrJsonOptions.Default.Converters)
o.JsonSerializerOptions.Converters.Add(converter);
o.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower;
o.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
o.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
});Or pass OpenEhrJsonOptions.Default to JsonContent / JsonSerializer in individual endpoints.
using System.Net.Http.Json;
// POST a composition
var content = JsonContent.Create(composition, options: OpenEhrJsonOptions.Default);
HttpResponseMessage response = await httpClient.PostAsync("/ehr/{ehr_id}/compositions", content);
// GET and deserialize
Composition? comp = await httpClient.GetFromJsonAsync<Composition>(
"/ehr/{ehr_id}/compositions/{version_uid}",
OpenEhrJsonOptions.Default);// Synchronous (e.g., reading a local file)
using var stream = File.OpenRead("composition.json");
Composition? comp = OpenEhrJsonSerializer.Deserialize<Composition>(stream);
// Asynchronous (e.g., reading an HTTP response stream)
using var responseStream = await httpResponse.Content.ReadAsStreamAsync();
Composition? comp = await OpenEhrJsonSerializer.DeserializeAsync<Composition>(
responseStream, cancellationToken);| openEHR type | .NET class | Notes |
|---|---|---|
DV_TEXT |
DvText |
Optional: formatting, hyperlink, language, encoding, mappings |
DV_CODED_TEXT |
DvCodedText |
Extends DV_TEXT; adds defining_code |
DV_PARAGRAPH |
DvParagraph |
Deprecated in RM 1.1.0 |
DV_QUANTITY |
DvQuantity |
magnitude, units; optional: precision, units_system, units_display_name, magnitude_status, accuracy |
DV_COUNT |
DvCount |
Integer magnitude |
DV_PROPORTION |
DvProportion |
numerator, denominator, type (enum ProportionKind) |
DV_ORDINAL |
DvOrdinal |
value (int) + symbol (DvCodedText) |
DV_SCALE |
DvScale |
value (double) + symbol (DvCodedText) |
DV_BOOLEAN |
DvBoolean |
|
DV_DATE_TIME |
DvDateTime |
ISO 8601 string |
DV_DATE |
DvDate |
|
DV_TIME |
DvTime |
|
DV_DURATION |
DvDuration |
ISO 8601 period string |
DV_IDENTIFIER |
DvIdentifier |
|
DV_URI |
DvUri |
|
DV_EHR_URI |
DvEhrUri |
|
DV_MULTIMEDIA |
DvMultimedia |
|
DV_PARSABLE |
DvParsable |
|
DV_INTERVAL |
DvInterval<T> |
Generic; bounds carry _type discriminators |
REFERENCE_RANGE |
ReferenceRange<T> |
Generic; available on all DvOrdered subtypes |
All DvOrdered subtypes (DV_QUANTITY, DV_COUNT, DV_PROPORTION, DV_ORDINAL, DV_SCALE, DV_DATE_TIME, DV_DATE, DV_TIME, DV_DURATION) fully support normal_status, normal_range, and other_reference_ranges.
| openEHR type | .NET class |
|---|---|
ITEM_TREE |
ItemTree |
ITEM_LIST |
ItemList |
ITEM_SINGLE |
ItemSingle |
ITEM_TABLE |
ItemTable |
CLUSTER |
Cluster |
ELEMENT |
Element |
HISTORY |
History<T> |
POINT_EVENT |
PointEvent<T> |
INTERVAL_EVENT |
IntervalEvent<T> |
| openEHR type | .NET class |
|---|---|
COMPOSITION |
Composition |
SECTION |
Section |
OBSERVATION |
Observation |
EVALUATION |
Evaluation |
INSTRUCTION |
Instruction |
ACTION |
Action |
ADMIN_ENTRY |
AdminEntry |
| openEHR type | .NET class |
|---|---|
PARTY_SELF |
PartySelf |
PARTY_IDENTIFIED |
PartyIdentified |
PARTY_RELATED |
PartyRelated |
PARTICIPATION |
Participation |
AUDIT_DETAILS |
AuditDetails |
ATTESTATION |
Attestation |
REVISION_HISTORY |
RevisionHistory |
REVISION_HISTORY_ITEM |
RevisionHistoryItem |
LINK |
Link |
FEEDER_AUDIT |
FeederAudit |
FEEDER_AUDIT_DETAILS |
FeederAuditDetails |
OBJECT_REF |
ObjectRef |
PARTY_REF |
PartyRef |
LOCATABLE_REF |
LocatableRef |
HIER_OBJECT_ID |
HierObjectId |
OBJECT_VERSION_ID |
ObjectVersionId |
GENERIC_ID |
GenericId |
ARCHETYPE_ID |
ArchetypeId |
TEMPLATE_ID |
TemplateId |
ARCHETYPED |
Archetyped |
| openEHR type | .NET class |
|---|---|
ORIGINAL_VERSION |
OriginalVersion<T> |
IMPORTED_VERSION |
ImportedVersion<T> |
CONTRIBUTION |
Contribution |
| openEHR type | .NET class |
|---|---|
EHR |
Ehr |
EHR_STATUS |
EhrStatus |
EHR_ACCESS |
EhrAccess |
VERSIONED_COMPOSITION |
VersionedComposition |
VERSIONED_EHR_STATUS |
VersionedEhrStatus |
VERSIONED_EHR_ACCESS |
VersionedEhrAccess |
Clarotech.OpenEHR.RM— openEHR Reference Model classes
Apache-2.0 — see LICENSE.txt