Firely .NET SDK

Firely Products

  • Back to all Firely Products

Firely .NET SDK

  • Introduction
  • Getting Started
  • Working with the Model
    • Introduction
    • Model Classes
    • FHIR Data Types
    • Backbone Elements
    • Enumerations
    • Choice Elements
    • Extensions
    • Code example for Patient
    • Bundles
    • Equality and Cloning
    • Dynamic Access to data
    • Navigating POCOs as a tree
      • Nodes which are lists
      • Common uses for PocoNode
    • FHIR model metadata
    • Other Features of the POCOs
    • Overview of the POCO model
    • Using multiple FHIR versions in one project
  • The FhirClient
  • Parsing and serialization
  • Validation of FHIR data
  • Using FhirPath
  • Working with CQL
  • FHIR Conformance data
  • Contact us
  • Release notes
Firely .NET SDK
    Buy vs Build banner

  • Firely Docs »
  • Firely .NET SDK »
  • Navigating POCOs as a tree
  • View page source

Navigating POCOs as a tree

Note

This section describes advanced functionality that can be safely skipped when you are learning the basics of the SDK.

Using the techniques described in the section on dynamic features, you can use EnumerateElements() and TryGetValue() to navigate the POCO model dynamically. By applying these methods recursively you can walk the entire POCO tree. In some scenarios, however, navigating only downward is not enough: both FhirPath and the validator need a couple of additional capabilities:

  • Ability to navigate back to the parent node

  • Ability to obtain a path from the root to the current node

Users of earlier SDK versions may recognize these features from the ITypedElement interface. Two limitations of that approach were that ITypedElement did not expose a parent (unless you wrapped nodes with ScopedNode) and it was a separate abstraction outside the POCO model, which made direct access to POCO-specific behavior harder.

SDK6 introduces PocoNode, a lightweight wrapper around POCOs that presents a POCO as a node in a tree. For backwards compatibility PocoNode implements both the ITypedElement and ISourceNode interfaces, so it can be used wherever ITypedElement was used before, while still providing direct access to the underlying POCO.

You can obtain a PocoNode for any element by calling ToPocoNode() on any Base instance.

Note

ToPocoNode() accepts an optional ModelInspector (see model metadata). Providing a ModelInspector is useful when deriving accurate type information for ITypedElement or for FhirPath’s ofType() when working with shared datatypes (see datatypes). In those cases the concrete POCO types may not fully align with the FHIR specification for a particular version.

Once you have a PocoNode, you can navigate both up and down the tree using the Parent property and the Children() method (to enumerate all children). Use Child() to get a specific child by name.

When you navigate down from the node created by ToPocoNode(), the PocoNode instances record the path back to that root node. Each PocoNode therefore exposes:

  • The node Name

  • The Index if the node is an element in a list

Use the extension method GetLocation() to obtain the full path from the root to the current node as a string.

Note

The parent pointers and location are established when you call ToPocoNode(). Holding references to parent resources can retain large object graphs in memory (for example, large Bundles), so exercise caution in memory-constrained or performance-critical environments.

Nodes which are lists

In the POCO tree, a node can be either a single node (represented by PocoNode) or a list of nodes (represented by PocoNodeList). Both derive from the abstract class PocoNodeOrList and implement IEnumerable<PocoNode>. This allows you to traverse the tree using LINQ — for example SelectMany(Children) — similar to how ITypedElement is often consumed.

Because any child can be a single POCO or a collection of POCOs (if the fhir data is repeating), the return type of Child() is PocoNodeOrList?. The Parent property will always provide a single PocoNode (or null, if the node in question is the root of the tree).

Common uses for PocoNode

The SDK provides several extension methods that leverage the extra information in PocoNode. These make PocoNode a suitable replacement for the earlier ScopedNode used by the FhirPath engine and the profile validator.

Examples include:

  • Resolve() — resolves a local reference in the POCOs represented by this PocoNode.

  • ContainedResources() — returns the nodes that represent contained resources.

  • Descendants() — returns all child nodes recursively.

  • NavigateTo() — navigates to a simple dotted path below the current node.

These utilities make tree-based operations and validation straightforward while keeping direct access to the underlying POCOs. Navigating POCOs as a tree

Previous Next

© Copyright 2024, Firely.

Built with Sphinx using a theme provided by Read the Docs.