# openEHR Reference Model in JSON format **Category:** [Formats](https://discourse.openehr.org/c/formats/123) **Created:** 2025-01-16 08:27 UTC **Views:** 242 **Replies:** 13 **URL:** https://discourse.openehr.org/t/openehr-reference-model-in-json-format/6194 --- ## Post #1 by @Martin_Koch A while ago, I was tasked with creating a (nearly) complete list of all attributes that can be stored in a composition as defined by the openEHR reference model. The goal was to compile an example of all paths that can be populated with information when creating a composition for the Clinical Data Repository (CDR). Understanding these paths also facilitates formulating AQL queries. For instance, an end time for the context can be stored at: context/end_time/value Similarly, the ID of an external reference of the composer can be stored at: composer/external_ref/id/value Initially, I manually created this list by navigating through various web pages of the reference model and constructing the paths myself. This process was quite tedious, so we developed a script to scrape the reference model pages, extracting all tables containing class information. The outcome is a JSON file containing all classes and attributes, which can be easily processed by machines. I am sharing the JSON file here because it could be beneficial for anyone encountering a similar challenge. Furthermore, this initiative might inspire future revisions of the reference model to be published in a similar machine-readable format. [20250116_openEHR_RM.json|attachment](upload://ndhSkhuCT9vd8pjIWXO6ydTS1ht.json) (207.2 KB) I am also sharing an excel file as an example of the path list that can be created automatically. [20250116_RM_path_output.xlsx|attachment](upload://znuobBjq895qbrzHWSYl7DVsvjo.xlsx) (165.5 KB) --- ## Post #2 by @borut.jures Great initiative @Martin_Koch to better understand the information that gets stored in a CDR. You can compare the JSON created via scraping to the "official" computable representation of the RM found in BMM files: https://github.com/openEHR/specifications-ITS-BMM/tree/master/components/RM/Release-1.1.0 Your JSON includes descriptions that are not present in the BMM files and are only part of the HTML ( :clap:). To avoid scraping the openEHR site, you could work directly on AsciiDoc files: https://github.com/openEHR/specifications-RM/tree/master/docs There are also an alternative UML diagrams (with descriptions): https://neoehr.com/openehr/uml/rm110/c/action --- ## Post #3 by @ian.mcnicoll Thanks Martin, This is incredibly useful, many thanks for this contribution. The good news is that the RM changes so slowly (for mostly good reasons) that keeping it current may not be quite as hard, though @borut.jures suggestions are helpful. We need to think about how to make this a bit easier to maintain, and of course, translate. --- ## Post #4 by @ian.mcnicoll One minor suggestion, which is to change 'occurence' to 'existence', which is as I understand it , what applies to RM attributes, whereas 'occurrence' applies to any overlying archetype constraint. --- ## Post #5 by @Seref [quote="ian.mcnicoll, post:4, topic:6194"] ‘occurence’ to ‘existence’, [/quote] From the top of my memory, existence indicates an attribute having value, and occurence indicates cardinality of the values. Happy to be corrected. --- ## Post #6 by @Martin_Koch Thank you so much for the comments. @borut.jures When looking into the BMM, I have found a JSON version here: https://github.com/openEHR/specifications-ITS-BMM/tree/master/adl_test/Release-1.0.0/BMM/json Maybe I have "re-invented the wheel" here :smiley: . @ian.mcnicoll I am certainly going to have a look into the difference of occurrence vs existence. --- ## Post #7 by @ian.mcnicoll Me too - I may not be quite right about 'existence' in this context @borut.jures - do you have any thoughts on this. From what I can see BMM expresses existence as a isMandatory boolean - as per @Seref's interpretation, --- ## Post #8 by @Seref > A constraint on occurrences is used only with cADL object nodes (not attribute nodes), to indicate how many times in runtime data an instance of a given class conforming to a particular constraint can occur. It only has significance for objects which are children of a container attribute, since by definition, the occurrences of an object which is the value of a single valued attribute can only be `0..1` or `1..1` , and this is already defined by the attribute `existence` [Archetype Definition Language 1.4 (ADL1.4)](https://specifications.openehr.org/releases/AM/Release-2.2.0/ADL1.4.html#_occurrences) The above is what I was remembering. I'm too busy to check but why would we have these in any representation of the rm? These are constraints to be applied on rm, not properties of RM classes. Have I completely forgotten the basics? :) --- ## Post #9 by @borut.jures These two are both defined in AM BMM (for constraints as already mentioned): - `C_ATTRIBUTE.existence` - `C_OBJECT.occurrences` Example of an AM JSON: - `existence` defines that the attribute `category` is required in a RM type/class - `occurrences` defines that the `category`attribute is always of type `DV_CODED_TEXT` as a single element and not a `list` of `DV_CODED_TEXT` items ``` "attributes": [ { "_type": "C_ATTRIBUTE", "rm_attribute_name": "category", "existence": { "_type": "Multiplicity_interval", "lower": 1, "upper": 1, "lower_unbounded": false, "upper_unbounded": false, "lower_included": true, "upper_included": true }, "children": [ { "_type": "C_COMPLEX_OBJECT", "rm_type_name": "DV_CODED_TEXT", "occurrences": { "_type": "Multiplicity_interval", "lower": 1, "upper": 1, "lower_unbounded": false, "upper_unbounded": false, "lower_included": true, "upper_included": true }, ``` `occurrence` in JSON is parsed from the `Attributes` column of the "blue" tables that describe an RM class. This column shows the `existence` which can be one of two values: **0..1**, **1..1** (basically true/false defining if the attribute is mandatory). `occurrence` in @Martin_Koch JSON is not the same as `C_OBJECT.occurrences`. It should be `existence` or `is_mandatory` (as proposed by @ian.mcnicoll). --- @Martin_Koch Note that `cardinality = <|>=0|>` is missing in JSON (for example `ADDRESSED_MESSAGE.addressees` in JSON): ``` "ADDRESSED_MESSAGE": { "attributes": { "addressees": { "occurrence": "1..1", "type": [ "List", "String" ] }, ``` ...while in BMM: ``` ["ADDRESSED_MESSAGE"] = < properties = < ["addressees"] = (P_BMM_CONTAINER_PROPERTY) < type_def = < container_type = <"List"> type = <"String"> > cardinality = <|>=0|> > ``` We have 3 somewhat confusing properties: `existence`, `occurrences` and `cardinality` :wink: --- ## Post #10 by @ian.mcnicoll The JSON file you found is essentially BMM as JSON (from what I understand) which is fine but a bit abstract, whereas your approach adds some helpful implications for human consumers as well as the node descriptions, so you are absolutely not re-inventing the wheel. I can use what you have delivered right out of the box to support a pice of work I am doing, and will save a ton of work. --- ## Post #11 by @ian.mcnicoll It is confusing so here is my understanding, and thinking aloud as I 've dived into BMM and P_BMM BMM expresses 4 ideas `is_mandatory`: boolean - is the attribute mandatory or not (may be deprecated in favour of `is_nullable`) 'existence()' : A function which expresses 'Is_mandatory' in '0..1' or '1..1' format. Note that there is no idea as existence '0..*' - where a container of some sort (array, list etc) is needed, then this is expressed as aList: string So this where `cardinality` comes in and applies only to containers. 'cardinality`: The number of items that can be carried in a container. I suspect that at RM level this is largely used to set a minimum of '1' for containers, where the parent attribute is optional, which essentially prevents an empty container object. e,g, from the EVENT_CONTEXT class ``` ["participations"] = (P_BMM_CONTAINER_PROPERTY) < name = <"participations"> type_def = < container_type = <"List"> type = <"PARTICIPATION"> > cardinality = <|>=1|> > ``` There is no `is_mandatory` attribute on `participations` but if you add a participations object, the `cardinality` is '>=1' i.e it cannot be empty. This is a universal rule in openEHR but I was never sure how it was expressed technically (it does not appear in the UML AFAICT. When we get int o applying archetype constraints on top of the RM (AOM) we have 2 concepts that essentially mirror the BMM concepts C_EXISTENCE: which would allow us to assert that an optional attribute in the RM is mandatory in the archetype/template. C_CARDINALITY: which allows us to adjust the allowed number o items in a container. Some archetype editors used to allow this to be set but the general consensus was that cardinality, though potentiuallity quite elegant , was actually very confusing for modellers, particularly when set alongside ' occurences' which is new idea in the AOM, and much more useful. 'occurrences': within a container object, how many times can a specific child object appear. This is what we apply when we say that an ELEMENT or CLUSTER is '0..*' etc whereas 'cardinality' is the number of children (orf any type( that can appear in the container. You can see how this could allow some very creative use of a mix of cardinality/ occurrences to express e.g optionality but it just got too hard for most of us to apply safely and explain to others. So although `existence` and `cardinality` statements appear in raw ADL, they are not supported (correctly IMO) in most tooling UI. So my take , finally is that @Martin_Koch would be better to change `occurrences' to 'existence` or 'is_mandatory`which is actually the original constraint. --- ## Post #12 by @ian.mcnicoll To follow-up, the other critical thing that has been added in your JSON, is of course the description, which does not appear in BMM in any way. So the question is if/how we can make that process a bit less onerous in the future so that e.g the Ascidocs which are the source of truth for the text, can be easily parsed to connect the descriptions to e.g some sort of format derived from BMM. The P_BMM flavour is actually very nicely expressed - export that as JSON, add a description pulled from Asciidocs , clearly tagged with the corresponding P_BMM statement, and I think we have something very interesting. https://specifications.openehr.org/releases/ITS-BMM/development/components/RM/latest/openehr_rm_ehr.bmm --- ## Post #13 by @borut.jures AM and RM as JSON (from BMM files with descriptions, variants and methods from Asciidocs): https://discourse.openehr.org/t/bmm-as-json/6198 --- ## Post #14 by @Martin_Koch I am attaching an updated version of the JSON here. "occurrence" has been changed to "existence", as was suggested. [20250120_openEHR_RM.json|attachment](upload://jKnXIwOZo5W4NEqln3WjSqP0kNU.json) (206.9 KB) --- **Canonical:** https://discourse.openehr.org/t/openehr-reference-model-in-json-format/6194 **Original content:** https://discourse.openehr.org/t/openehr-reference-model-in-json-format/6194