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.
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.
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.
@type
When converting JSON-LD to RDF, @type translates to
one of the following:
rdf:type edgedatatype mark for a Literal nodePossible ways to specify this in YAML-LD are the following:
@context, but there we can only say that the node is an IRI,
we cannot specify a particular rdf:type
rdfs:domain or rdfs:range properties
@type keywordUsing 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).
If a segment of a YAML document has to be repeated more than once, one of the following approaches can be taken:
@id, and then address it by the given identifier
Use YAML anchors & aliases as shown in .
Two alternative approaches have been proposed to implement the Extended profile:
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.
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.
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.
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.
Any error reported in a recursive processing step MUST result in the failure of this processing step.
Both block sequences and flow sequences are directly aligned with an array in the internal representation.
Any error reported in a recursive processing step MUST result in the failure of this processing step.
Both block mappings and flow mappings are directly aligned with a map in the internal representation.
Any error reported in a recursive processing step MUST result in the failure of this processing step.
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.
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.
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.
This algorithm describes the steps to convert each element from the internal representation into corresponding YAML nodes by recursively processing each element |n|.
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 ).
The YAML-LD Basic profile is specified in [[yaml-ld-10]]. See Encoding, Mapping Key Types, alias handling, Streams, and Stream Processing.
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.
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.
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.
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.
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`:
- 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|.
- Otherwise, et |converted value| to |value|.
- 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.
The {{JsonLdOptions}} type is used to pass various options to the {{JsonLdProcessor}} methods.
This specification reuses the following option defined in [[JSON-LD11-API]]:
| 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. |
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:
These updates are intended to be compatible with other updates to the {{LoadDocumentCallback}}, such as Process HTML as defined in [[JSON-LD11-API]].
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"
};
TODO: Implementations for Extended Internal Representation.
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-LDbasic_to_extended(basic_document: YAML-LD) → YAML-LDrdflib 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:
extended_to_basic(basic_to_extended(document)) = documentbasic_to_extended(extended_to_basic(document)) = document
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.) |
&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 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.
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.
The editors would especially like to thank the following individuals for making significant contributions to the authoring and editing of this specification: