Cameleer

FHIR data formats

The fhirJson and fhirXml data formats parse HL7 FHIR resources from JSON or XML into a value and serialize resources back, which also converts between the two FHIR encodings.

Name: fhirJson, fhirXml · Crate: cameleer-soap · Cargo feature: soap · Apache Camel: FHIR JSon, FHIR XML

When to use it

  • Accept FHIR resources (Patient, Observation, Bundle...) from apps and EHRs and route on their content.
  • Convert FHIR XML from older systems to FHIR JSON for modern APIs, or the other way round.
  • Strip narratives or selected elements before passing a resource to an analytics job or an LLM, so it only sees the fields it needs.

Marshal and unmarshal

directioninput bodyoutput body
unmarshal (fhirJson / fhirXml)FHIR JSON / FHIR XML texta resource value in the FHIR JSON model: resourceType, arrays for repeating elements, _name for primitive extensions, typed numbers and booleans
marshal (fhirJson / fhirXml)a resource value, or FHIR JSON / XML textFHIR JSON / XML text; sets Content-Type to application/fhir+json / application/fhir+xml

Because marshal also accepts FHIR text in either encoding, marshal: fhirXml directly on a JSON body converts it to XML (and marshal: fhirJson on XML converts to JSON). XML output follows the specification's element order. Decimals keep their lexical form (1.50 stays 1.50).

Example

Convert a FHIR JSON Patient to FHIR XML.

yaml example: fhir-json-to-xml
- route:
    id: fhir-json-to-xml
    from:
      uri: direct:fhir-xml
      steps:
        - marshal:
            fhirXml:
              prettyPrint: false
json
{"resourceType": "Patient", "id": "p1", "active": true,
 "name": [{"family": "Doe", "given": ["Jane"]}], "birthDate": "1980-01-01"}
xml
<Patient xmlns="http://hl7.org/fhir"><id value="p1"/><active value="true"/><name><family value="Doe"/><given value="Jane"/></name><birthDate value="1980-01-01"/></Patient>

Unmarshal an Observation, route on its value, and drop the narrative before forwarding:

yaml example: fhir-observation-route
- route:
    id: fhir-observation
    from:
      uri: direct:fhir-observation
      steps:
        - unmarshal:
            fhirJson: {}
        - setHeader:
            name: glucose
            simple: "${body.valueQuantity.value}"
        - marshal:
            fhirJson:
              suppressNarratives: true
        - setBody:
            simple: "${header.glucose} -> ${body}"
json
{"resourceType": "Observation", "status": "final",
 "text": {"status": "generated", "div": "<div xmlns=\"http://www.w3.org/1999/xhtml\">Glucose 5.4</div>"},
 "code": {"coding": [{"system": "http://loinc.org", "code": "15074-8"}]},
 "valueQuantity": {"value": 5.4, "unit": "mmol/L"}}
text
5.4 -> {"resourceType":"Observation","status":"final","code":{"coding":[{"system":"http://loinc.org","code":"15074-8"}]},"valueQuantity":{"value":5.4,"unit":"mmol/L"}}

Rust DSL

rust
b.from("direct:fhir-rust")
    .unmarshal(DataFormatDefinition::new("fhirXml"))
    .marshal(DataFormatDefinition::new("fhirJson"));

Options

optiondefaultdescription
fhirVersionR4R4, R4B, R5 or DSTU3: selects the type registry (element order, types).
prettyPrintfalseIndent the output.
suppressNarrativesfalseDrop the text narrative.
omitResourceIdfalseLeave out the resource id.
encodeElements(none)Only encode these elements, comma separated (Patient.name or name).
dontEncodeElements(none)Leave out these elements.
stripVersionsFromReferencesfalseRemove /_history/n from references.
contentTypeHeadertrueSet Content-Type on marshal.

summaryMode, serverBaseUrl, parserOptions, preferTypes, forceResourceId, overrideResourceIdWithBundleEntryFullUrl, encodeElementsAppliesToChildResourcesOnly and dontStripVersionsFromReferencesAtPaths are accepted for compatibility.

Known limitation: suppressNarratives currently removes every element named text at any depth, not only the resource narrative. That also drops CodeableConcept.text, Annotation.text and similar fields, so do not enable it when you need those (HAPI only removes the Narrative).

Differences from Apache Camel

Camel uses HAPI FHIR and produces HAPI model classes. Here resources are plain values in the FHIR JSON shape, so Simple paths like ${body.name[0].family} read them, and there is no HAPI validation (the FHIR component offers validation against the base profiles).

Common questions

How do I convert FHIR XML to JSON?

marshal: fhirJson: {} on the XML text (or unmarshal: fhirXml then marshal: fhirJson).

How do I read a field of a FHIR resource in a route?

Unmarshal with fhirJson (or fhirXml) and use Simple: ${body.name[0].given[0]}, ${body.valueQuantity.value}.

Which FHIR versions are supported?

DSTU3, R4 (default), R4B and R5 serialization rules, chosen with fhirVersion.

Found a problem?

If something on this page doesn't match what Cameleer does, or you hit a bug while building with it, please help fix it, whether you are a person or a coding agent: open an issue that describes what you saw, then fork the repository, fix it, add or update a test, run cargo test --workspace, and open a pull request. CONTRIBUTING.md explains the ground rules.

Edit this page on GitHub