Skip to content

YAML – Information Models

YAML - Data Model and Representation Graph

Section titled “YAML - Data Model and Representation Graph”

To effectively use and understand YAML, it’s helpful to grasp its underlying information model. When a YAML document is processed, it’s transformed into an abstract data structure often referred to as a ‘representation graph’ or ‘node graph’. This graph is what applications interact with, rather than the raw YAML text directly.

The representation of native application data in YAML is modeled as a rooted, connected, directed graph of tagged nodes. Let’s break this down:

  • Graph: A collection of nodes (data items) and edges (relationships between them).
  • Directed: Relationships have a direction (e.g., a mapping node points to its key and value nodes).
  • Rooted: The graph has a single starting point (the root node of the YAML document).
  • Connected: All nodes are reachable from the root.
  • Tagged Nodes: Each node in the graph has a tag that specifies its data type (e.g., string, integer, sequence, mapping).

The overall transformation can be thought of as:

Application Data ⇔ YAML Node Graph (Scalars, Sequences, Mappings with Tags) ⇔ YAML Textual Representation

The YAML node graph is primarily composed of three kinds of nodes:

Represent single, atomic data values. Their content is a sequence of Unicode characters. Examples include strings, numbers, booleans, dates, and null values. Each scalar node has a tag (e.g., !!str, !!int, !!bool, !!null, !!timestamp) that defines how its character content should be interpreted.

Represent an ordered series of zero or more other nodes. This corresponds to lists or arrays in programming languages. A sequence node contains an ordered list of child nodes. Its typical tag is !!seq.

Represent an unordered association of key-value pairs. This corresponds to dictionaries, objects, or hash maps. A mapping node contains a set of pairs, where each pair consists of a key node and a value node. Keys within a mapping must be unique. The typical tag for a mapping node is !!map. While keys are often scalar nodes, YAML allows keys to be complex nodes (sequences or mappings themselves).

Sequences and mappings are collectively referred to as ‘collection nodes’.

Every node in the YAML graph has a tag. Tags are crucial because they determine the interpretation of the node’s content. While YAML often infers tags based on syntax (e.g., 123 is inferred as !!int, true as !!bool), tags can be specified explicitly:

  • Global Tags (Shorthand): !!tagname (e.g., !!str, !!map). These are part of the standard YAML tag set.
  • Primary Tags (Application-Specific or Local): !tagname (e.g., !person, !config-setting). These can be defined by applications.
  • Secondary Tags (!<prefix>!tagname): Used for more complex URI-based tagging, less common in everyday use.

Example of a Node Graph Structure:

# YAML Document
user_profile: # Root node, implicitly a Mapping (!!map)
name: Alice # Scalar node (!!str) child of 'user_profile'
age: 30 # Scalar node (!!int) child of 'user_profile'
hobbies: # Sequence node (!!seq) child of 'user_profile'
- reading # Scalar node (!!str) child of 'hobbies'
- coding # Scalar node (!!str) child of 'hobbies'

This YAML would be represented internally as a graph where user_profile is a mapping node. This mapping node has three child entries: one for name (key) pointing to Alice (value, a scalar string node), one for age (key) pointing to 30 (value, a scalar integer node), and one for hobbies (key) pointing to a sequence node. The hobbies sequence node, in turn, has two child scalar string nodes: reading and coding.

Anchors and Aliases: Creating Graphs (Not Just Trees)

Section titled “Anchors and Aliases: Creating Graphs (Not Just Trees)”

YAML’s anchor (&) and alias (*) mechanism allows a single node to be referenced multiple times within the document. This means the representation graph can indeed be a general graph with cycles or shared substructures, not just a simple tree. When an alias is encountered, it points to the same node instance that was marked by the anchor.

default_address: &addr
street: 123 Main St
city: Anytown
billing_address: *addr
shipping_address: *addr

In this case, billing_address and shipping_address both point to the exact same mapping node instance defined by &addr.

  • Portability: It provides a common way to think about YAML data across different programming languages and environments.
  • Understanding YAML Libraries: It clarifies how YAML parsers and serializers work internally.
  • Advanced Data Structuring: It helps in designing complex data relationships using features like anchors, aliases, and custom tags.
  • Debugging: Understanding the expected node structure can aid in diagnosing issues with YAML parsing or generation.

For those interested in the most formal details, the official YAML specification (available at yaml.org) provides an in-depth description of its information model and processing rules.