Parse and enumerate all the fhir elements

493 Views Asked by At

I am using the Firely nuget package to parse a Patient FHIR resource from a bundle. The keyValuePair.Value type is object and for complex fhir datatypes contains nested objects. How do I parse and extract all the fhir elements and its values to a csv format?

Is there an easier way to parse and enumerate the elements without having to typecast the resource first and then extract each individual element inside that resource?

string fhirBundle = GetFHIRBundleFromFile();

FhirJsonParser fhirJsonParser = new FhirJsonParser();
Bundle bundle = fhirJsonParser.Parse<Bundle>(fhirBundle);

foreach (var entry in bundle.Entry)
{
    switch (entry.Resource)
    {
        case Patient:
            Patient patient = (Patient)entry.Resource;
            foreach (KeyValuePair<string, object> keyValuePair in patient)
                  Console.WriteLine(keyValuePair.Key + ": " + keyValuePair.Value.ToString());
             
            break;
        default:
            Console.WriteLine("Resource is not of type Patient")   
            break;
    }
}
 
1

There are 1 best solutions below

3
Mirjam Baltus On

A note first: you will potentially loose a lot of information by converting the tree that is your FHIR object into a flat file that is CSV. Be aware of that, so you can choose if this is what you want.

Maybe using the ElementModel from the SDK is an option. The serializers do not serialize to CSV, only to the FHIR defined formats. So you will need to add extra code to make sure your values are encoded or escaped correctly when outputting CSV, but this is an improved example from yours where I've used the ITypedElement to more easily walk through the tree that is the FHIR resource:

// add using statements for Hl7.Fhir.ElementModel and Hl7.Fhir.Serialization

JsonSerializerOptions options = new JsonSerializerOptions().ForFhir();

string jsonInput = File.ReadAllText("bundle.json");

try
{
    Bundle bundle = JsonSerializer.Deserialize<Bundle>(jsonInput, options);

    foreach (var entry in bundle.Entry)
    {
        if (entry.Resource is Patient)
        {
            var resource = entry.Resource.ToTypedElement();
            foreach (var element in resource.Descendants())
            {
                if (element.Value != null)
                    Console.Write(element.Name + ":" + element.Value + ":");
                else // this is a complex element
                    Console.Write(element.Name + ":");
            }
            Console.WriteLine();
        }
    }
}
catch (DeserializationFailedException e)
{
    Console.WriteLine($"Parsing failed with message {e.Message}");
}

You could have used the ITypedElement on parsing the Bundle already as well, instead of parsing that with the regular parser. Then you would have to navigate to the Entry element first, before the step where you would output the data.