This document is a W3C Draft Group Note that collects Extended YAML-LD Profile ideas: possible uses of additional [[YAML]] features together with [[JSON-LD11]] and the [[[JSON-LD11-API]]] [[JSON-LD11-API]] when serializing Linked Data as YAML-LD.

Normative requirements for YAML-LD today are defined only in the YAML-LD specification. Everything in this note—including algorithms, profiles, and API discussion—is informative exploration only.

Topics here include YAML node tags, anchors and aliases, and extended internal representations. None of this alters conformance for the current Basic Profile or obliges implementations until such time as a future specification explicitly adopts it.

This Draft Group Note is informative and does not define a conformance class for products or implementations. Normative requirements for YAML-LD are defined only in the YAML-LD specification (see also the Editor’s Draft). Normative language elsewhere in this note describes behavior that could be required if this material were incorporated into a future specification; it does not alter conformance to the current YAML-LD specification on its own.

Terminology

This document uses the following terms as defined in external specifications and defines terms specific to this note.

The term media type is imported from [[RFC6838]].

The term JSON is imported from [[JSON]].

The terms JSON-LD document, and value object are imported from [[JSON-LD11]].

The terms internal representation, and documentLoader are imported from [[JSON-LD11-API]].

The terms array, boolean, map, map entry, null, and string are imported from [[INFRA]].

The term number is imported from [[ECMASCRIPT]].

The terms YAML, YAML representation graph, YAML stream, YAML directive, TAG directive, YAML document, YAML sequence (either block sequence or flow sequence), YAML mapping (either block mapping or flow mapping), node, scalar, node anchor, node tags, and alias node, are imported from [[YAML]].

The term content negotiation is imported from [[RFC9110]].

The terms RDF literal, language-tagged string, datatype IRI, and language tag are imported from [[RDF11-CONCEPTS]].

The terms fragment and fragment identifier in this document are to be interpreted as in [[URI]].

The term Linked Data is imported from [[LINKED-DATA]].

The following terms are defined in the YAML-LD specification:

The YAML-LD extended profile is defined in this document.

The JSON-LD extended internal representation is defined in this document as an extension of the internal representation.

Extended YAML-LD Profile

Motivation

The YAML-LD specification relies upon YAML to serialize Linked Data to the extent that YAML is compatible with JSON, which simplifies the operation and usage of YAML-LD. However, the more expressive feature set of YAML invites us to represent Linked Data in a more expressive way.

In the cases described above, one of the possible expressive methods is a specific feature of YAML language. To leverage those methods, we propose an Extended YAML-LD Profile which will implement all such features.

This document specifies the Extended YAML-LD Profile as a W3C Group Note. The YAML-LD Basic profile remains defined in [[yaml-ld-10]].

Specify node @type

When converting JSON-LD to RDF, @type translates to one of the following:

  • an rdf:type edge
  • a datatype mark for a Literal node

Possible ways to specify this in YAML-LD are the following:

  • In the @context, but there we can only say that the node is an IRI, we cannot specify a particular rdf:type
  • Using [[RDF-SCHEMA]] and [[OWL2-SYNTAX]] based logical reasoning, for instance, via rdfs:domain or rdfs:range properties
  • Inline, using the @type keyword
  • Using a YAML Tag, as shown below:

                    %TAG !xsd! http://www.w3.org/2001/XMLSchema%23
                    ---
                    "@context": https://schema.org
                    "@id": https://w3c.github.io/yaml-ld/
                    dateModified: !xsd:date 2023-06-26
                  

    Here, %TAG declares the !xsd: prefix for tags used in the document. YAML treats tags as IRIs, which brings it close to the LD family of data formats. Note that the directives section must be separated from the main document with --- (a line containing exactly three hyphens).

Reduce duplication

If a segment of a YAML document has to be repeated more than once, one of the following approaches can be taken:

  • Repeat the segment as many times as necessary
  • If the segment represents a node, designate it once with a YAML-LD @id, and then address it by the given identifier
  • Use YAML anchors & aliases as shown in .

Approaches

Two alternative approaches have been proposed to implement the Extended profile:

Extended Internal Representation

This approach implies extending the JSON-LD internal representation to allow a more complete expression of native data types within YAML-LD, and allows use of the complete [[[JSON-LD11-API]]] [[JSON-LD11-API]] Application Programming Interface to manipulate extended YAML-LD documents.

A YAML-LD document complies with the YAML-LD extended profile of this specification if it follows the normative statements from this specification and can be transformed into the JSON-LD extended internal representation, then back to a conforming YAML-LD document, without loss of semantic information.

The YAML-LD extended profile allows full use of anchor names and alias nodes. YAML-LD documents MUST use alias nodes defined by a previous node with a corresponding anchor; otherwise, a loading-document-failed error MUST be detected, and processing aborted.

If the {{JsonLdOptions/processingMode}} API parameter is `yaml-ld-extended`, the processing result will be in the extended internal representation.

When processing using the YAML-LD Basic profile, alias nodes are resolved as specified in YAML-LD 1.0.

Conversion to the Internal Representation

YAML-LD processing is defined by converting YAML to the internal representation and using [[[JSON-LD11-API]]] to process on that representation, after which the representation is converted back to YAML. As information specific to a given YAML document structure is lost in this transformation, much of the specifics of that original representation are therefore lost in that conversion, limiting the ability to fully round-trip a YAML-LD document back to an equivalent representation. Consequently, round-tripping in this context is limited to preservation of the semantic representation of a document, rather than a specific syntactic representation.

The conversion process represented here is compatible with the description of "Composing the Representation Graph" from the 3.1.2 Load section of [[YAML]]. The steps described below for converting to the internal representation operate upon that .

When operating using the YAML-LD Basic profile, it is intended that the common feature provided by most YAML libraries of transforming YAML directly to JSON satisfies the requirements for parsing a YAML-LD file.

As a developer, I want to be able to convert JSON-LD documents to YAML-LD by simply serializing the document using any standard YAML library, So that the resulting YAML is valid YAML-LD, resolving to the same graph as the original JSON-LD.

Converting a YAML stream

A YAML-LD stream MAY contain more than one YAML-LD document, as specified in Streams.

Converting a YAML stream MUST apply Stream Processing for document cardinality, the default `extractAllScripts` value of false, empty-stream errors, and the shape of the JSON-LD [=internal representation=]. Each constructed value is the result of for the corresponding YAML document.

Any error reported in a recursive processing step MUST result in the failure of this processing step.

Converting a YAML document

From the YAML grammar, a YAML document MAY be preceded by a Document Prefix and/or a set of directives followed by a YAML bare document, which is composed of a single node.

  1. Create an empty |named nodes| map which will be used to associate each alias node with the node having the corresponding node anchor.
  2. Set |document content| to the result of processing the node associated with the YAML bare document, using the appropriate conversion step defined in this section. If that node is not one of the following, a loading-document-failed error has been detected and processing is aborted.
    A node may be of another type, but this is incompatible with JSON-LD, where the top-most node must be either an array or map.
  3. The conversion result is |document content|.

Any error reported in a recursive processing step MUST result in the failure of this processing step.

Converting a YAML sequence

Both block sequences and flow sequences are directly aligned with an array in the internal representation.

  1. Set |sequence content| to an empty array.
  2. If the sequence has a node anchor, add a reference from the anchor name to the sequence in the |named nodes| map.
  3. For each node |n| in the sequence, append the result of processing |n| to |sequence content| using the appropriate conversion step.
  4. The conversion result is |sequence content|.

Any error reported in a recursive processing step MUST result in the failure of this processing step.

Converting a YAML mapping

Both block mappings and flow mappings are directly aligned with a map in the internal representation.

  1. Set |mapping content| to an empty map.
  2. Otherwise, if the mapping has a node anchor, add a reference from the anchor name to the mapping in the |named nodes| map.
  3. For each |entry| in the mapping composed of a key/value pair:
    1. Set |key| and |value| to the result of processing |entry| using the appropriate conversion step.
    2. If |key| is not a string, a mapping-key-error error has been detected and processing MUST be aborted.
    3. Add a new entry to |mapping content| using |key| and |value|.
  4. The conversion result is |mapping content|.

Any error reported in a recursive processing step MUST result in the failure of this processing step.

Converting a YAML scalar

  1. If the {{JsonLdOptions/processingMode}} option is `yaml-ld-extended`, and node |n| has a node tag |t|, |n| is mapped as follows:
    1. If |t| resolves with a prefix of `tag:yaml.org,2002:`, the conversion result is mapped through the YAML Core Schema.
    2. Otherwise, if |t| resolves with a prefix of `https://www.w3.org/ns/i18n#`, and the suffix does not contain an underscore (`"_"`), the conversion result is a language-tagged string with value taken from |n|, and a language tag taken from the suffix of |t|.
      Node tags including an underscore (`"_"`), such as `i18n:ar-eg_rtl` describe a combination of language and text direction. See The `i18n` Namespace in [[JSON-LD11]].
    3. Otherwise, the conversion result is an RDF literal with value taken from |n| and datatype IRI taken from |t|.
  2. Otherwise, the conversion result is mapped through the YAML Core Schema.

Implementations may retain the representation as an YAML Integer, or YAML Floating Point, but a JSON-LD processor must treat them uniformly as a number, although the specific type of number value SHOULD be retained for round-tripping.

Converting a YAML alias node

The conversion result is the value of the entry in the |named nodes| map having the node entry. If none exist, the document is invalid, and processing MUST end in failure.

If an alias node is encountered when processing the YAML representation graph and the {{JsonLdOptions/processingMode}} option is not equal to `yaml-ld-extended`, the conversion result is the value of the target node, as described in basic profile alias handling.

If a cycle is detected, a processing error MUST be returned, and processing aborted.

Conversion to YAML

The conversion process from the internal representation involves turning that representation back into a YAML representation graph and relies on the description of "Serializing the Representation Graph" from the 3.1.1 Dump section of [[YAML]] for the final serialization.

As the internal representation is rooted by either an array or a map, the process of transforming the internal representation to YAML begins by preparing an empty representation graph which will be rooted with either a YAML mapping or YAML sequence.

Although outside of the scope of this specification, processors MAY use YAML directives, including TAG directives, and Document markers, as appropriate for best results. Specifically, if the {{JsonLdOptions/processingMode}} API parameter is `yaml-ld-extended`, the document SHOULD use the `%YAML` directive with version set to at least `1.2`. To improve readability and reduce document size, the document MAY use a `%TAG` directive appropriate for RDF literals contained within the representation.

The use of `%TAG` directives in YAML-LD is similar to the use of the `PREFIX` directive in [[?Turtle]] or the general use of terms as prefixes to create Compact IRIs in [[JSON-LD11]]: they not change the meaning of the encoded scalars.

Although allowed within the YAML Grammar, some current YAML parsers do not allow the use of `"#"` within a tag URI. Substituting the `"%23"` escape is a workaround for this problem, that will hopefully become unnecessary as implementations are updated.

A concrete proposal in that direction would be to use a tag at the top-level of any "idiomatic" YAML-LD document, applying to the whole object/array that makes the document.

It might also include a version to identify the specification that it relates to, allowing for version announcement that could be used for future-proofing.

The following block is one example:

        !yaml-ld
        $context: http://schema.org
        $type: Person
        name: Pierre-Antoine Champin
        

See for a %TAG serialization illustration of the extended internal representation.

Converting From the Internal Representation

This algorithm describes the steps to convert each element from the internal representation into corresponding YAML nodes by recursively processing each element |n|.

  1. If |n| is an array, the conversion result is a YAML sequence with child nodes of the sequence taken by converting each value of |n| using this algorithm.
  2. Otherwise, if |n| is an map, the conversion result is a YAML mapping with keys and values taken by converting each key/value pair of |n| using this algorithm.
  3. Otherwise, if |n| is an RDF literal:
    1. If the datatype IRI of |n| is `xsd:string`, the conversion is a YAML scalar with the value taken from that value of |n|.
    2. Otherwise, if |n| is a language-tagged string, the conversion is a YAML scalar with the value taken from that value of |n| and a node tag constructed by appending that language tag to `https://www.w3.org/ns/i18n#`.
    3. Otherwise, the conversion is a YAML scalar with the value taken from that value of |n| and a node tag taken from the datatype IRI of |n|.
  4. Otherwise, if |n| is a number, the conversion result is a YAML scalar with the value taken from |n|.
  5. Otherwise, if |n| is a boolean, the conversion result is a YAML scalar with the value either `true` or `false` based on the value of |n|.
  6. Otherwise, if |n| is null, the conversion result is a YAML scalar with the value `null`.
  7. Otherwise, conversion result is a YAML scalar with the value taken from |n|.

Application Profiles

This section identifies two application profiles for operating with YAML-LD:

Application profiles allow publishers to use YAML-LD either for maximum interoperability, or for maximum expressivity. The YAML-LD Basic profile provides for complete round-tripping between YAML-LD documents and JSON-LD documents. The YAML-LD extended profile allows for fuller use of YAML features to enhance the ability to represent a larger number of native datatypes and reduce document redundancy.

Application profiles can be set using the {{JsonLdProcessor}} API interface, as well as an HTTP request profile (see ).

YAML-LD Basic Profile

The YAML-LD Basic profile is specified in [[yaml-ld-10]]. See Encoding, Mapping Key Types, alias handling, Streams, and Stream Processing.

YAML-LD Extended Profile

The YAML-LD extended profile extends the YAML Core Schema, allowing node tags to specify RDF literals by using a JSON-LD extended internal representation capable of directly representing RDF literals.

As specified in Encoding, YAML-LD streams in the YAML-LD extended profile MUST be encoded in UTF-8.

As specified in Mapping Key Types, keys used in a YAML mapping MUST be strings.

YAML-LD documents MAY use alias nodes, as long as dereferencing these aliases does not result in a loop.

Consider something like `!id` as a local tag to denote IRIs.

The JSON-LD Extended Internal Representation

This specification defines the JSON-LD extended internal representation, an extension of the JSON-LD internal representation.

In addition to maps, arrays, and strings, the internal representation allows native representation of numbers, boolean values, and nulls. The extended internal representation allows for native representation of RDF literals, both with a datatype IRI, and language-tagged strings.

When transforming from the extended internal representation to the internal representation — for example when serializing to JSON or to the YAML-LD Basic profile — implementations MUST transform RDF literals to the closest native representation of the internal representation:

An alternative would be to transform such literals to JSON-LD value objects, and we may want to provide a means of transforming between the internal representation and extended internal representation using value objects, but this treatment is consistent with [[YAML]] Core Schema Tag Resolution.

The Application Programming Interface

This specification extends the [[[JSON-LD11-API]]] [[JSON-LD11-API]] Application Programming Interface and the [[[JSON-LD11-FRAMING]]] [[JSON-LD11-FRAMING]] Application Programming Interface to manage the serialization and deserialization of [[YAML]] and to enable an option for setting the YAML-LD extended profile.

JsonLdProcessor

The JSON-LD Processor interface is the high-level programming structure that developers use to access the JSON-LD transformation methods. The updates below is an experimental extension of the {{JsonLdProcessor}} interface defined in the JSON-LD 1.1 API [[JSON-LD11-API]] to serialize output as YAML rather than JSON.

{{JsonLdProcessor/compact()}}
Updates step 10 of the {{JsonLdProcessor/compact()}} algorithm to serialize the the result as YAML rather than JSON as defined in .
{{JsonLdProcessor/expand()}}
Updates step 9 of the {{JsonLdProcessor/expand()}} algorithm to serialize the the result as YAML rather than JSON as defined in .
{{JsonLdProcessor/flatten()}}
Updates step 7 of the {{JsonLdProcessor/flatten()}} algorithm to serialize the the result as YAML rather than JSON as defined in .
Updates step 22 of the frame() algorithm to serialize the the result as YAML rather than JSON as defined in .
{{JsonLdProcessor/fromRdf()}}
Updates step 3 of the {{JsonLdProcessor/fromRdf()}} algorithm to serialize the the result as YAML rather than JSON as defined in .
Updates the RDF to Object Conversion algorithm before step 2.6 as follows:
Otherwise, if the {{JsonLdOptions/useNativeTypes}} flag is set, the {{JsonLdOptions/processingMode}} parameter is `yaml-ld-extended`, and the datatype IRI of |value| is not `xsd:string`:
  1. If |value| is a language-tagged string set |converted value| to a new RDF literal composed of the lexical form of |value| and datatype IRI composed of `https://www.w3.org/ns/i18n#` followed by the language tag of |value|.
  2. Otherwise, et |converted value| to |value|.
{{JsonLdProcessor/toRdf()}}
Updates the Object to RDF Conversion algorithm before step 10 as follows:
  1. Otherwise, if |value| is an RDF literal, |value| is left unmodified. This will only be the case when processing a value from an extended internal representation.

JsonLdOptions

The {{JsonLdOptions}} type is used to pass various options to the {{JsonLdProcessor}} methods.

This specification reuses the following option defined in [[JSON-LD11-API]]:

processingMode
Possible values are detailed in the table below.
Value Meaning
json-ld-1.0 Processor MUST raise a profile-error, as JSON-LD 1.0 algorithms are not supported by YAML-LD.
Not Provided, or json-ld-1.1 The document conforms to YAML-LD Basic profile.
yaml-ld-extended The document MUST be processed in conformance with YAML-LD extended profile.
Other values starting with yaml-ld Reserved for future versions of this specification.
Other Values Can be used by YAML-LD processors to enable custom processing algorithms.
When YAML-LD extended profile is used for serializing the internal representation (or extended internal representation) into a YAML representation graph:
When used for the {{documentLoader}}, it causes documents of type `application/ld+yaml` to be parsed into a YAML representation graph and generates an internal representation (or extended internal representation):

Remote Document and Context Retrieval

This section describes an update to the built-in {{LoadDocumentCallback}} to load YAML streams and documents into the internal representation, or into the extended internal representation if the {{JsonLdOptions/processingMode}} parameter is `yaml-ld-extended`.

The {{LoadDocumentCallback}} algorithm in [[JSON-LD11-API]] is updated as follows:

  • Step 2 is updated to prefer Content-Type `application/ld+yaml`, followed by `application/yaml`, followed by the other specified Content-Types.
  • After step 5, add the following processing step: Otherwise, if the retrieved resource's Content-Type is either `application/yaml` or any media type with a `+yaml` suffix as defined in [[RFC6839]] transform |document| to the internal representation (or extended internal representation) as described in . Additionally, if the {{RemoteDocument/profile}} parameter includes `http://www.w3.org/ns/json-ld#extended`, set the {{JsonLdOptions/processingMode}} option to `yaml-ld-extended`.

These updates are intended to be compatible with other updates to the {{LoadDocumentCallback}}, such as Process HTML as defined in [[JSON-LD11-API]].

YamlLdErrorCode

The YamlLdErrorCode represents the collection of valid YAML-LD error codes, which extends the {{JsonLdErrorCode}} definitions.

          enum YamlLdErrorCode {
            "invalid-encoding",
            "mapping-key-error",
            "profile-error"
          };
        
invalid-encoding
The character encoding of an input is invalid.
mapping-key-error
A YAML mapping key was found that was not a string.
profile-error
The parsed YAML document contains features incompatible with the specified profile.

Implementations

TODO: Implementations for Extended Internal Representation.

Convert Extended YAML-LD to Basic YAML-LD and back

This approach is simpler than the Extended Internal Representation because it does not require any changes to the internal structures of existing JSON-LD libraries.

Instead, we implement two API functions:

extended_to_basic(extended_document: YAML-LD) → YAML-LD
  • Converts the document to Basic YAML-LD form
basic_to_extended(basic_document: YAML-LD) → YAML-LD
  • Converts YAML-LD → JSON
  • Performs JSON-LD expansion → the resulting JSON-LD document
  • Converts Expanded JSON-LD document back to YAML-LD
  • Converts it to the Extended form, making use of YAML-LD features to express the document more concisely.
You won't typically need to perform these steps manually because libraries such as rdflib will take care of them under the covers, but it can help with troubleshooting and optimization to know what's going on. So, you start with YAML, convert it to JSON, perform JSON-LD Expansion, convert that to YAML-LD, and do any necessary basic → extended or extended → basic conversion on the YAML-LD. Alternatively, your library might do YAML-LD expansion directly on the initial YAML document, and then do any necessary basic → extended or extended → basic conversion on the YAML-LD.

Both of these functions recursively process the source document. Every branch and leaf are copied as is, unless they match one of the following cases.

Generally, these two equalities do not hold:

When the extended → basic conversion resolves YAML tags we no longer know where the original document used tags and where it used @type calls. Thus, information is lost.

Both of these functions lose information about anchors and references because they're resolved by the YAML processor underlying the implementation.

extended_to_basic basic_to_extended
YAML Tags Convert YAML !tags → @type JSON-LD keywords (nothing)
Anchors and aliases Resolve anchors and aliases (nothing)
Comments Keep as-is Remove
(Due to JSON-LD & Expansion.)

YAML tag shorthands → @type declarations

              %TAG !xsd! http://www.w3.org/2001/XMLSchema%23
              ---
              "@context": https://schema.org
              "@id": https://github.com/gkellogg
              "@type": Person
              name: !xsd!string Gregg Kellogg
              birthDate: !xsd!date 1970-01-01
                
                  "@context":
                    - "@import": https://schema.org
                    - xsd: "http://www.w3.org/2001/XMLSchema#"
                  "@id": https://github.com/gkellogg
                  "@type": Person
                  name: Gregg Kellogg
                  birthDate:
                    "@value": 1970-01-01
                    "@type": xsd:date
                

&anchors and *aliases

Substitute every *alias with the content of the &anchor alias references to. This is standard behavior of YAML tools and libraries.

Fragment identifiers

Fragment identifiers used with application/ld+yaml are treated as in RDF syntaxes, as per RDF 1.1 Concepts and Abstract Syntax [[RDF11-CONCEPTS]] and do not follow the process defined for application/yaml.

Perhaps more on fragment identifiers from Issue 31.

Acknowledgements

In Memoriam

Gregg Kellogg was a central figure in the story of JSON-LD and YAML-LD. He worked tirelessly on JSON-LD and many other specifications for more than a decade, right up until his death on September 6th, 2025. Gregg's passion for solving hard problems with finesse was only exceeded by his willingness to collaborate with and encourage others in reaching that destination. The JSON-LD and broader Linked Data communities will be forever grateful for Gregg's consistent, careful, and kindly delivered contributions during their most formative years.

Contributions

The editors would especially like to thank the following individuals for making significant contributions to the authoring and editing of this specification: