JSON-LD Framing allows developers to query by example and force a specific tree layout to a JSON-LD document.

This specification describes a superset of the features defined in [[[JSON-LD10-FRAMING]]] [[JSON-LD10-FRAMING]] and, except where noted, the algorithms described in this specification are fully compatible with documents created using the previous community standard.

This document has been developed by the JSON-LD Working Group and was derived from the JSON-LD Community Group's Final Report.

There is a live JSON-LD playground that is capable of demonstrating the features described in this document.

Set of Documents

This document is one of three JSON-LD 1.1 Recommendations produced by the JSON-LD Working Group:

Introduction

JSON-LD is a lightweight syntax to serialize Linked Data [[LINKED-DATA]] in JSON [[RFC8259]]. Its design allows existing JSON to be interpreted as Linked Data with minimal changes. As with other representations of Linked Data which describe directed graphs, a single directed graph can have many different serializations, each expressing exactly the same information. Developers typically work with trees, represented as JSON objects. While mapping a graph to a tree can be done, the layout of the end result must be specified in advance. A Frame can be used by a developer on a JSON-LD document to specify a deterministic layout for a graph.

Using delimiters around a chunk of data is known as "framing". JSON-LD uses JSON delimiters such as { and } to separate statements about a particular subject. JSON-LD also allows subjects to reference other subjects through the use of their identifiers, expressed as strings.

However, given that JSON-LD represents one or more graphs of information, there is more than one way to frame the statements about several related subjects into a whole document. In fact, a graph of information can be thought of as a long list of independent statements (aka triples) that are not bundled together in any way.

The JSON-LD Framing API enables a developer to specify exactly how they would like data to be framed, such that statements about a particular subject are bundled together, delimited via { and }, and such that the subjects they relate to "nest" into a particular tree structure that matches what their application expects.

How to Read this Document

This document is a detailed specification for a serialization of Linked Data in JSON. The document is primarily intended for the following audiences:

A companion document, the JSON-LD 1.1 specification [[JSON-LD11]], specifies the grammar of JSON-LD documents.

To understand the basics in this specification you must first be familiar with JSON, which is detailed in [[RFC8259]]. You must also understand the JSON-LD 1.1 Syntax specification [[JSON-LD11]], which is the base syntax used by all of the algorithms in this document, and the JSON-LD 1.1 API [[JSON-LD11-API]]. To understand the API and how it is intended to operate in a programming environment, it is useful to have working knowledge of the JavaScript programming language [[ECMASCRIPT]] and WebIDL [[WEBIDL]]. To understand how JSON-LD maps to RDF, it is helpful to be familiar with the basic RDF concepts [[RDF11-CONCEPTS]].

This document can highlight changes since the [[[JSON-LD10]]] version. Select to changes.

Contributing

There are a number of ways that one may participate in the development of this specification:

Typographical conventions

Terminology

This document uses the following terms as defined in external specifications and defines terms specific to JSON-LD.

Algorithm Terms

The Following terms are used within specific algorithms.

Syntax Tokens and Keywords

This specification adds a number of keywords (framing keywords) to the ones defined in the JSON-LD 1.1 Syntax specification [[JSON-LD11]]:

@default
Used in Framing to set the default value for an output property when the framed node object does not include such a property.
@embed
Used in Framing to override the value of object embed flag within a specific frame. Valid values for @embed as the following:
@always
Always embed node objects as property values, unless this would cause a circular reference.
@once
Just a single value within a given node object should be embedded, other values of other properties use a node reference. This is the default value if neither @embed nor object embed flag is specified.
The specific node object chosen to embed depends on ordering. If the {{JsonLdOptions/ordered}} flag is true, this will be the first node object encountered, otherwise, it may be any node object.
@never
Always use a node reference when serializing matching values.

Any other value for @embed is invalid and indicates that an invalid @embed value error has been detected and processing is aborted.

@explicit
Used in Framing to override the value of explicit inclusion flag within a specific frame.
@null
Used in Framing when a value of null should be returned, which would otherwise be removed when Compacting.
@omitDefault
Used in Framing to override the value of omit default flag within a specific frame.
@requireAll
Used in Framing to override the value of require all flag within a specific frame.

All JSON-LD tokens and keywords are case-sensitive.

Features

JSON-LD 1.1 introduces new features that are compatible with [[[JSON-LD10]]] [[JSON-LD10]], but if processed by a JSON-LD 1.0 processor may produce different results. Processors default to `json-ld-1.1`, unless the {{JsonLdOptions/processingMode}} API option is explicitly set to `json-ld-1.0`. Publishers are encouraged to use the @version map entry within a context set to `1.1` to ensure that JSON-LD 1.0 processors will not misinterpret JSON-LD 1.1 features.

Framing

Framing is used to shape the data in a JSON-LD document, using an example frame document which is used to both match the flattened data and show an example of how the resulting data should be shaped. Matching is performed by using properties present in in the frame to find objects in the data that share common values. Matching can be done either using all properties present in the frame, or any property in the frame. By chaining together objects using matched property values, objects can be embedded within one another.

A frame also includes a context, which is used for compacting the resulting framed output.

For example, assume the following JSON-LD frame:

    
    

This frame document describes an embedding structure that would place objects with type Library at the top, with objects of type Book that were linked to the library object using the contains property embedded as property values. It also places objects of type Chapter within the referencing Book object as embedded values of the Book object.

When using a flattened set of objects that match the frame components:

    
    

The Frame Algorithm can create a new document which follows the structure of the frame:

If processing mode is not json-ld-1.0, or the omit graph flag is true, the top-level @graph entry may be omitted.

    
    

The Framing Algorithm does this by first expanding both the input frame and document. It then creates a map of flattened subjects. The outer-most node object within the frame is used to match objects in the map, in this case looking for node objects which have an @type of Library, and a contains property with another frame used to match values of that property. The input document contains exactly one such node object. The value of contains also has a node object, which is then treated as a frame to match the set of subjects which are contains values of the Library object, and so forth.

Matching on Properties

In addition to matching on types, a frame can match on one or more properties.

For example, the following frame selects object based on property values, rather than `@type`.

    
    

This will generate the same framed results as when selecting on `@type`, as the property values are unique to each node object.

See to see how matching can be restricted to match node objects containing all, versus any such listed property.

Wildcard Matching

The empty map (`{}`) is used as a wildcard, which will match a property if it exists in a target node object, independent of any specific value.

For example, the following frame selects object based on property wildcarding, rather than `@type`.

    
    

This will generate the same framed results as when selecting on `@type`, as the matched properties are distinct to each node object.

Match on the Absence of a Property

The empty array (`[]`) is used for match none, which will match a node object only if a property does not exist in a target node object.

For example, the following frame selects object based on the absence of properties, rather than `@type`.

    
    

This will generate the same framed results as when selecting on `@type`, the property that is excluded uniquely identifies each node object. Note that additional properties with the value `null` are added for those properties explicitly excluded.

Matching on Values

Frames can be matched based on the presence of specific property values. These values can themselves use wildcards, to match on a specific or set of values, language tags, types, or base direction.

For an example, we'll use an multilingual version of the library example with more complex value representations.

    
    

By matching on an attribute of a value, we can match frames having that attribute, and limit results to property values that match. In this case, we'll frame the Library and Book objects on values only in latinized Greek (`el-Latn`):

    
    

This generates the following framed results:

Matching on `@id`

Frames can be matched if they match a specific identifier (`@id`). This can be illustrated with the original Flattened library objects input using a frame which matches on specific `@id` values:

    
    

This generates the following framed results:

Frames can also be matched from an array of identifiers. Within a frame, it is acceptable for `@id` to have an array value, where the individual values are treated as IRIs.

    
    

This generates the following framed results:

Empty Frame

An empty frame matches any node object, even if those objects are embedded elsewhere, causing them to be serialized at the top level.

    
    

This generates the following framed results:

Default content

A frame may specify properties that don't exist in an input file. If the explicit inclusion flag is false, the framing algorithm will add a property and value to the result. The @default property in a node object or value object, or as a value of `@type`, provides a default value to use in the resulting output document. If there is no @default value, the property will be output with a null value. (See for ways to avoid this).

The value of the property in the frame is not otherwise used in the output document. It's purpose is for frame matching and finding default values. Note the description value for Library in the following example.

    
    

Default values may also be used for `@type`, similar to other properties. In this case, a matched node object without an `@type` will take the value of the default object from the frame. The default object has a value which is a single IRI. If multiple IRIs are specified, only the first will be used as the default type.

The frame matches objects having specific property values, and provides defaults for `@type` for matched objects.

    
    

Data missing specific values for `@type`, but which matches based on other property values.

    
    

Framing Flags

Framing can be controlled using API options, or by adding framing keywords within the frame as described in .

Framing flags set using keywords have effect only for the frame in which they appear, and for implicit frames which are created for objects where no frame object exists.

Object Embed Flag

The object embed flag determines if a referenced node object is embedded as a property value of a referencing object, or kept as a node reference. The initial value for the object embed flag is set using the {{JsonLdOptions/embed}} option. Consider the following frame based on the default @once value of the object embed flag:

      
      

Because, the default for the object embed flag is @once (in addition to the explicit inclusion flag being false), non-listed properties are added to the output, and implicitly embedded using a default empty frame. As a result, the same output used in the Framed library objects above is generated, assuming that the {{JsonLdOptions/ordered}} flag is true.

However, if the @embed property is added explicitly with a value of @never, the values for Book and Chapter will be excluded.

      
      

To illustrate the case where @once does not expand values, consider an alternate library example where books are doubly indexed.

      
      

When framed using the same frame with the default @embed of @once, only the "books" property will have content, if the {{JsonLdOptions/ordered}} flag is true, and the "contains" property will use a reference.

If we use a frame using "@embed": "@always", both properties will include expanded values.

      
      

Explicit inclusion flag

The explicit inclusion flag used to determine properties which will be included in the output document. The default value is false, which means that properties present in an input node object that are not in the associated frame will be included in the output object. If true, only properties present in the input frame will be placed into the output. The initial value for the explicit inclusion flag is set using the {{JsonLdOptions/explicit}} option.

For example, take an expanded version of the library frame which include some properties from the input, but omit others.

      
      

The resulting output will exclude properties for Book which are not explicitly listed in the frame object:

Note that the Library object contains a null description property, as it is explicitly called for in the frame using "description": {}. The creator property does not exist in the output, because it is not explicit.

Omit default flag

The omit default flag changes the way framing generates output when a property described in the frame is not present in the input document. The initial value for the omit default flag is set using the {{JsonLdOptions/omitDefault}} option. See for a further discussion.

Consider the following input document:

      
      

To illustrate where the omit default flag is useful, consider the following frame, which does not use @omitDefault:

      
      

The resulting output will include a "child" property with the value null, which may not always be desired:

Note that because the option "@embed": "@always" is specified in the frame under the child property, that "child": null appears in the output for matches that do not have that property, which may be undesirable. To prevent this default null output from occurring, the @omitDefault may be set to true like so:

      
      

Which yields this (desirable) output:

Omit graph flag

The omit graph flag determines if framed output containing a single node object is contained within @graph, or not. The initial value for the omit graph flag is set using the {{JsonLdOptions/omitGraph}} option, or based on the processing mode; if processing mode is json-ld-1.0, the output always includes a @graph entry, otherwise, the @graph entry is used only to describe multiple node objects, consistent with compaction. See for a further discussion.

The result is the same as the original Flattened library objects example, but a `@graph` at the top-level. Example 5 shows the results with the omit graph flag set to `true`, which is the default value when the processing mode is set to the default `json-ld-1.1`. The top-level object can be enclosed within `@graph` by setting the processing mode to `json-ld-1.0`, or by setting the omit graph flag to `false`.

Require all flag

The require all flag is used in frame matching to determine when a node object from an input document matches a frame. When matching, an object may include @type and other properties, a match is made when any property value in the object matches the node pattern in the frame object if the value of the require all flag is false (the default). If the flag value is true, then all properties in the frame object must be present in the node object for the node to match.

The following frame matches on multiple properties, including the absence of a property. Using the Flattened library objects example, we can match on an object containing both the title and description or title and creator properties. If we were to use `@requireAll` set to `false`, then we could match on the presence of any property, not all properties.

      
      

This will, again, reproduce the desired framed output:

Reverse Framing

A frame may include @reverse, or a value of a term defined using @reverse to invert the relationships in the output object. For example, the Library example can be inverted using the following frame:

    
    

Using the flattened library example above, results in the following:

There is an asymmetry between regular properties and reverse properties. Normally, when framing a node object, unless the explicit inclusion flag is set, all properties of the node are included in the output, but reverse properties are not, as they are not actually properties of the node.

To include reverse properties in the output, add them explicitly to the frame. Note that if the reverse relationship does not exist, it will simply be left out of the output.

Framing Named Graphs

Frames can include @graph, which allows information from named graphs contained within a JSON-LD document to be exposed within it's proper graph context. By default, framing uses a merged graph, composed of all the node objects across all graphs within the input. By using @graph within a frame, the output document can include information specifically from named graphs contained within the input document.

The following example uses a variation on our library theme where information is split between the default graph, and a graph named http://example.org/graphs/books:

    
    
    
    

There is one class of products that can claim conformance to this specification: JSON-LD Processors.

A conforming JSON-LD Processor is a system which can perform the Framing operation in a manner consistent with the algorithms defined in this specification.

JSON-LD Processors MUST NOT attempt to correct malformed IRIs or language tags; however, they MAY issue validation warnings. IRIs are not modified other than conversion between relative and absolute IRIs.

Unless specified using {{JsonLdOptions/processingMode}} API option, the processing mode is set using the @version entry in a local context and affects the behavior of algorithms including expansion and compaction. Once set, it is an error to attempt to change to a different processing mode, and processors MUST generate, a {{JsonLdErrorCode/"processing mode conflict"}} error and abort further processing.

The algorithms in this specification are generally written with more concern for clarity than efficiency. Thus, JSON-LD Processors MAY implement the algorithms given in this specification in any way desired, so long as the end result is indistinguishable from the result that would be obtained by the specification's algorithms.

In algorithm steps that describe operations on keywords, those steps also apply to keyword aliases.

Implementers can partially check their level of conformance to this specification by successfully passing the test cases of the JSON-LD framing test suite. Note, however, that passing all the tests in the test suite does not imply complete conformance to this specification. It only implies that the implementation conforms to aspects tested by the test suite.

Framing

The following sections describe algorithms for framing JSON-LD documents. Framing is the process of taking a JSON-LD document, which expresses a graph of information, and applying a specific graph layout (called a Frame).

Framing makes use of the Node Map Generation algorithm to place each object defined in the JSON-LD document into a map of flattened subjects, allowing them to be operated upon by the Framing algorithm.

All algorithms described in this section are intended to operate on language-native data structures. That is, the serialization to a text-based JSON document isn't required as input or output to any of these algorithms.

Reference to JSON data structures are interpreted using their internal representation for the purpose of describing algorithms.

Framing Algorithm

Overview

A valid JSON-LD Frame is a superset of a valid JSON-LD document, allowing additional content, which is preserved through expansion. The Grammar defined in the JSON-LD 1.1 Syntax specification [[JSON-LD11]] is extended as follows:

Algorithm

The framing algorithm takes five required input variables and one optional input variable. The required inputs are a framing state (state), a list of subjects to frame, an input frame (expanded frame), a parent used to collect partial frame results, and an active property. The optional input variable is the {{JsonLdOptions/ordered}} flag.

The algorithm adds elements to parent either by appending the element to parent, if it is an array, or by appending it to an array associated with active property in parent, if it is a map. Note that if parent is an array, active property MUST be null, and if it is a map, it MUST NOT be null.

  1. If frame is an array, set frame to the value of the array, which MUST be a valid frame. If frame is determined to be invalid, an invalid frame error has been detected and processing is aborted.
    1. Frame MUST be a map.
    2. If frame has an `@id` entry, its value MUST be either an array containing a single empty map as a value, a valid IRI or an array where all values are valid IRIs.
    3. If frame has a `@type` entry, its value MUST be either an array containing a single empty map as a value, an array containing a map with a entry whose key is `@default`, a valid IRI or an array where all values are valid IRIs.
  2. Initialize flags embed, explicit, and requireAll from object embed flag, explicit inclusion flag, and require all flag in state overriding from any property values for @embed, @explicit, and @requireAll in frame.
  3. Create a list of matched subjects by filtering subjects against frame using the Frame Matching algorithm with state, subjects, frame, and requireAll.
  4. For each id and associated node object node from the set of matched subjects, in code point order by id if the optional {{JsonLdOptions/ordered}} flag is true:
    1. Initialize output to a new map with @id and id.
    2. If the embedded flag in state is `false` and there is an existing embedded node in parent associated with graph name and id in state, do not perform additional processing for this node.
    3. Otherwise, if the embedded flag in state is `true` and either embed is @never or if a circular reference would be created by an embed, add output to parent and do not perform additional processing for this node.
    4. Otherwise, if the embedded flag in state is `true`, embed is @once, and there is an existing embedded node in parent associated with graph name and id in state, add output to parent and do not perform additional processing for this node.
    5. If graph map in state has an entry for id:
      1. If frame does not have a @graph entry, set recurse to true, unless graph name in state is @merged and set subframe to a new empty map.
      2. Otherwise, set subframe to the first entry for @graph in frame, or a new empty map, if it does not exist, and set recurse to true, unless id is @merged or @default.
      3. If recurse is true:
        1. Set the value of graph name in state to id.
        2. Set the value of embedded flag in state to `false`.
        3. Invoke the algorithm using a copy of state with the value of graph name set to id and the value of embedded flag set to `false`, the keys from the graph map in state associated with id as subjects, subframe as frame, output as parent, and @graph as active property.
    6. If frame has an `@included` entry, invoke the algorithm using a copy of state with the value of embedded flag set to `false`, subjects, frame, output as parent, and `@included` as active property.
    7. For each property and objects in node, in code point order by property if the optional {{JsonLdOptions/ordered}} flag is true:
      1. If property is a keyword, add property and objects to output.
      2. Otherwise, if property is not in frame, and explicit is true, processors MUST NOT add any values for property to output, and the following steps are skipped.
      3. For each item in objects:
        1. If item is a map with the property @list, then each listitem in the list is processed in sequence and added to a new list map in output:
          1. If listitem is a node reference, invoke the algorithm using a copy of state with the value of embedded flag set to `true`, the value of @id from listitem as the sole item in a new subjects array, the first value from @list in frame as frame, list as parent, and @list as active property. If frame does not exist, create a new frame using a new map with properties for @embed, @explicit and @requireAll taken from embed, explicit and requireAll.
          2. Otherwise, append a copy of listitem to @list in list.
        2. If item is a node reference, invoke the algorithm using a copy of state with the value of embedded flag set to `true`, the value of @id from item as the sole item in a new subjects array, the first value from property in frame as frame, output as parent, and property as active property. If frame does not exist, create a new frame using a new map with properties for @embed, @explicit and @requireAll taken from embed, explicit and requireAll.
        3. Otherwise, append a copy of item to active property in output.
      4. For each non-keyword property and objects in frame (other than `@type) that is not in output:
        1. Let item be the first value in objects, which MUST be a frame object.
        2. Set property frame to the first value in objects or a newly created frame object if value is objects. property frame MUST be a map.
        3. Skip property and property frame if property frame contains @omitDefault with a value of true, or does not contain @omitDefault and the value of the omit default flag in state is true.
        4. Add property to output with a new map having a property @preserve and a value that is a copy of the value of @default in frame if it exists, or the string @null otherwise.
      5. If frame has the property @reverse, then for each reverse property and sub frame that are the values of @reverse in frame:
        1. Create a @reverse property in output with a new map reverse dict as its value.
        2. For each reverse id and node in the map of flattened subjects that has the property reverse property containing a node reference with an @id of id:
          1. Add reverse property to reverse dict with a new empty array as its value.
          2. Invoke the algorithm using a copy of state with the value of embedded flag set to `true`, the reverse id as the sole item in a new subjects array, sub frame as frame, null as active property, and the array value of reverse property in reverse dict as parent.
      6. Once output has been set are required in the previous steps, add output to parent.

Frame Matching Algorithm

The Frame Matching Algorithm is used as part of the Framing algorithm to determine if a particular node object matches the criteria set in a frame. In general, a node object matches a frame if it meets the matches on @type, @id, or if it matches given one of several different properties. If the require all flag is true, all properties must have defaults or match for the frame to match.

As matching is performed on expanded node objects, all values will be in the form of an array.

Node matching uses a combination of JSON constructs to match any, zero, or some specific values:

[] (match none)
An empty array matches no values, or a value which is, itself, an empty array.
{} (wildcard)
An array containing an empty object (after excluding any properties which are framing keywords) matches any value that is present, and does not match if there are no values.
[IRI+]
One or more strings in the form of an IRI, used for matching on @type and @id, which allows a match on any of the listed IRIs.
[frame object] (node pattern)
A non-empty frame object, used to match specific values using recursive node matching.
[value object] (value pattern)
A value object, used to match a specific value. Within a value object, the values for @value, @type, and @language may also be an array of one or more string values, values of `@language` are compared without regard to case..

The frame matching algorithm takes the framing state (state), a list of subjects to match from the map of flattened subjects (subjects), a frame to match against (frame), and the requireAll flag and returns a list of matched subjects by filtering each node in subjects as follows:

All properties, including @id and @type, but no other keywords are considered when matching a frame.

  1. node matches if frame has no properties.
  2. If requireAll is true, node matches if all properties (property) in frame match any of the following conditions. Or, if requireAll is false, if any of the properties (property) in frame match any of the following conditions. For the values of each property from frame in node:
    1. If property is @id:
      1. property matches if the @id property in frame includes any IRI in values.
      2. Otherwise, property matches if the @type property in frame is wildcard or match none.
      Framing works on map of flattened subjects, and the act of flattening ensures that all subjects have an @id property; thus the "@id": [] pattern would never match any node object. The "@id": [{}] pattern would match any node object and is equivalent to not specifying a @id property in frame at all
    2. Otherwise, if property is @type:
      1. property matches if the @type property in frame includes any IRI in values.
      2. Otherwise, property matches if values is not empty and the @type property in frame is wildcard.
      3. Otherwise, property matches if values is empty and the @type property in frame is match none.
      4. Otherwise, property matches if the @type property in frame is a default object.
      5. Otherwise, property does not match.
    3. If property is @id or @type and does not match, node does not match, and processing is terminated.
    4. Otherwise, the value of property in frame MUST be empty, or an array containing a valid frame.
    5. property matches if values is empty, or non existent, the value of property in frame is a map containing only the @default entry with any value, and any other property in node has a non-default match.
    6. node does not match if values is not empty and the value of property in frame is match none, and further matching is aborted.
    7. Otherwise, property matches if values is not empty and the value of property in frame is wildcard.
    8. Otherwise, if the value of property in frame is a value pattern (value pattern): property matching is determined using the Value matching algorithm.
    9. Otherwise, for any node pattern (node pattern) which is one of the values of property in frame:
      1. Let value subjects be the list of subjects from the map of flattened subjects matching the node object values from values.
      2. Let matched subjects be the result of calling this algorithm recursively using state, value subjects for subjects, node pattern for frame, and the requireAll flag.
      3. property matches if matched subjects is not empty.
    10. Otherwise, property does not match.

Value Pattern Matching Algorithm

The Value Pattern Matching Algorithm is used as part of the Framing and Frame Matching algorithms. A value object matches a value pattern using the match none and wildcard patterns on @value, @type, and @language, in addition to allowing a specific value to match a set of values defined using the array form for each value object property.

The algorithm takes a value pattern (pattern) and value object (value) as parameters. Value matches pattern using the following algorithm:

  1. Let v1, t1, and l1 be the values of @value, @type, and @language in value, or null if none exists, where values of `@language` are normalized to lower case..
  2. Let v2, t2, and l2 be the values of @value, @type, and @language in value pattern, or null if none exists, where string values of `@language` are normalized to lower case..
  3. Value matches pattern when pattern is wildcard, or:
    1. v1 is in v2, or v1 is not null and v2 is wildcard, and
    2. t1 is in t2, or t1 is not null and t2 is wildcard, or null, or t1 is null and t2 is null or match none, and
    3. l1 is in l2, or l1 is not null and l2 is wildcard, or null, or l1 is null and l2 is null or match none.

The Application Programming Interface

This API provides a clean mechanism that enables developers to convert JSON-LD data into a variety of output formats that are easier to work with in various programming languages. If a JSON-LD API is provided in a programming environment, the entirety of the following API MUST be implemented.

The JSON-LD API uses Promises to represent the result of the various deferred operations. Promises are defined in [[ECMASCRIPT]]. General use within specifications can be found in [[promises-guide]]. Implementations MAY chose to implement in an appropriate way for their native environments as long as they generally use the same methods, arguments, and options and return the same results.

Interfaces are marked `[Exposed=JsonLd]`, which creates a global interface. The use of WebIDL in JSON-LD, while appropriate for use within browsers, is not limited to such use.

JsonLdProcessor

The JSON-LD Processor interface is the high-level programming structure that developers use to access the JSON-LD transformation methods. The definition below is an experimental extension of the interface defined in the JSON-LD 1.1 API [[JSON-LD11-API]].

It is important to highlight that implementations do not modify the input parameters. If an error is detected, the {{Promise}} is rejected with a JsonLdFramingError having an appropriate {{JsonLdFramingError/code}} and processing is stopped.

      [Exposed=JsonLd]
      partial interface JsonLdProcessor {
        static Promise<JsonLdRecord> frame(
          JsonLdInput input,
          JsonLdInput frame,
          optional JsonLdOptions options = {});
      };
    

The {{JsonLdProcessor}} interface frame() method Frames the given input using frame according to the steps in the Framing Algorithm:

  1. Create a new {{Promise}} promise and return it. The following steps are then executed asynchronously.
  2. If the provided input is a {{RemoteDocument}}, initialize remote document to input.
  3. Otherwise, if the provided input is a string representing the IRI of a remote document, await and dereference it as remote document using {{LoadDocumentCallback}}, passing input for url, and the {{LoadDocumentOptions/extractAllScripts}} option from options for extractAllScripts.
  4. Set expanded input to the result of using the {{JsonLdProcessor/expand()}} method either remote document or input if there is no remote document for input and options with {{JsonLdOptions/ordered}} set to false.
  5. If the provided frame is a {{RemoteDocument}}, initialize remote frame to frame.
  6. Otherwise, if the provided frame is a string representing the IRI of a remote document, await and dereference it as remote frame using {{LoadDocumentCallback}}, passing frame for url, and the {{LoadDocumentOptions/extractAllScripts}} option from options for extractAllScripts.
  7. Set expanded frame to the result of using the {{JsonLdProcessor/expand()}} method either remote frame or frame if there is no remote frame for input options the {{JsonLdOptions/frameExpansion}} option set to true, and the{{JsonLdOptions/ordered}} set to false.
  8. Set context to the value of @context from remote frame or frame, if it exists, or to a new empty context, otherwise.
  9. Set context base to the {{RemoteDocument/documentUrl}} from remote frame, if available, otherwise to the {{JsonLdOptions/base}} option from options.
  10. Initialize active context to the result of the Context Processing algorithm passing a new empty context as active context context as local context, and context base as base URL.
  11. Initialize an active context using context; the base IRI is set to the {{JsonLdOptions/base}} option from options, if set; otherwise, if the {{JsonLdOptions/compactToRelative}} option is true, to the IRI of the currently being processed document, if available; otherwise to null.
  12. Initialize inverse context to the result of performing the Inverse Context Creation algorithm.
  13. If frame has a top-level property which expands to @graph set the {{JsonLdOptions/frameDefault}} option to options with the value true.
  14. Initialize a new framing state (state) to an empty map.
    1. Set object embed flag in state to {{JsonLdOptions/embed}} with the default value `@once`.
    2. Set the embedded flag in state to `false`
    3. Set explicit inclusion flag in state to {{JsonLdOptions/explicit}} with the default value `false`.
    4. Set require all flag in state to {{JsonLdOptions/requireAll}} with the default value `false`.
    5. Set omit default flag in state to {{JsonLdOptions/omitDefault}} with the default value `false`.
    6. Set the graph name in state to either `@default` if {{JsonLdOptions/frameDefault}} is `true`, otherwise to `false`.
    7. Set the graph map in state to the result of performing the Node Map Generation algorithm on expanded input.
      1. If graph name in state is `@merged`, add an entry for `@merged` in graph map set to the result of the Merge Node Maps algorithm passing graph map.
    8. Set subject map in state to the map of flattened subjects which is the value of graph name in graph map.
  15. Initialize results as an empty array.
  16. Invoke the Framing algorithm, passing state, the keys from subject map in state for subjects, expanded frame, results for parent, and `null` as active property.
  17. If the processing mode is not json-ld-1.0, remove the @id entry of each node object in results where the entry value is a blank node identifier which appears only once in any property value within results.
  18. Recursively, replace all entries in results where the key is `@preserve` with the first value of that entry.
    The value of the entry will be an array with a single value; this will effectively replace the map containing `@preserve` with that value.
  19. Set compacted results to the result of using the {{JsonLdProcessor/compact()}} method using active context, inverse context, null for active property, results as element,, and the {{JsonLdOptions/compactArrays}} and {{JsonLdOptions/ordered}} flags from options.
    1. If compacted results is an empty array, replace it with a new map.
    2. Otherwise, if compacted results is an array, replace it with a new map with a single entry whose key is the result of IRI compacting `@graph` and value is compacted results.
    3. Add an @context entry to compacted results and set its value to the provided context.
  20. Recursively, replace all `@null` values in compacted results with `null`. If, after replacement, an array contains only the value `null` remove that value, leaving an empty array.
  21. If {{JsonLdOptions/omitGraph}} is false and compacted results does not have a top-level @graph entry, or its value is not an array, modify compacted results to place the non @context entry of compacted results into a map contained within the array value of @graph. If {{JsonLdOptions/omitGraph}} is true, a top-level @graph entry is used only to contain multiple node objects.
  22. Resolve the promise with compacted results, transforming compacted results from the internal representation to a JSON serialization.
input
The JSON-LD object or array of JSON-LD objects to perform the framing upon or an IRI referencing the JSON-LD document to frame.
frame
The frame to use when re-arranging the data of input; either in the form of an map or as IRI.
options
A set of options that MAY affect the framing algorithm such as, e.g., the input document's base IRI. The {{JsonLdOptions}} type defines default option values.

Error Handling

The JsonLdFramingError type is used to report processing errors.

      dictionary JsonLdFramingError {
        JsonLdFramingErrorCode code;
        USVString? message = null;
      };
      enum JsonLdFramingErrorCode {
        "invalid frame",
        "invalid @embed value"
      };
    

JSON-LD Framing extends the error interface and codes defined in [[JSON-LD11-API]].

code
a string representing the particular error type, as described in the various algorithms in this document.
message
an optional error message containing additional debugging information. The specific contents of error messages are outside the scope of this specification.

The JsonLdFramingErrorCode represents the collection of valid JSON-LD Framing error codes.

invalid frame
The frame is invalid.
invalid @embed value
The value for @embed is not one recognized for the object embed flag.

Data Structures

This section describes datatype definitions used within the JSON-LD API.

JsonLdContext

The {{JsonLdContext}} type is used to refer to a value that that may be a map, a string representing an IRI, or an array of maps and strings.

See {{JsonLdContext}} definition in the JSON-LD 1.1 API [[JSON-LD11-API]].

JsonLdOptions

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

      partial dictionary JsonLdOptions {
        (JsonLdEmbed or boolean)  embed         = "@once";
        boolean                   explicit      = false;
        boolean                   omitDefault   = false;
        boolean                   omitGraph;
        boolean                   requireAll    = false;
        boolean                   frameDefault  = false;
      };

      enum JsonLdEmbed {
        "@always",
        "@once",
        "@never"
      };
    

In addition to those options defined in the JSON-LD 1.1 API [[JSON-LD11-API]], framing defines these additional options:

embed
Sets the value object embed flag used in the Framing Algorithm. A boolean value of true sets the flag to @once, while a value of false sets the flag to @never.
explicit
Sets the value explicit inclusion flag used in the Framing Algorithm.
omitDefault
Sets the value omit default flag used in the Framing Algorithm
omitGraph
Sets the value omit graph flag used in the Framing Algorithm. If not set explicitly, it is set to false if processing mode is json-ld-1.0, true otherwise.
requireAll
Sets the value require all flag used in the Framing Algorithm.
frameDefault
Instead of framing a merged graph, frame only the default graph.

JsonLdEmbed enumerates the values of the {{JsonLdOptions/embed}} option:

@always
Always embed node objects as property values, unless this would cause a circular reference.
@once
Only a single value within a given node object should be embedded, other values of other properties use a node reference. This is the default value if neither @embed nor object embed flag is specified.
@never
Always use a node reference when serializing matching values.

See {{JsonLdOptions}} definition in the JSON-LD 1.1 API [[JSON-LD11-API]].

Security Considerations

See, Security Considerations in .

Privacy Considerations

See, Privacy Considerations in [[JSON-LD11]].

Internationalization Considerations

See, Internationalization Considerations in [[JSON-LD11]].

IANA Considerations

This section is included merely for standards community review and will be submitted to the Internet Engineering Steering Group if this specification becomes a W3C Recommendation.

A JSON-LD Frame uses the same MIME media type described in [[JSON-LD11]] along with a required profile parameter.

application/ld+json

Type name:
application
Subtype name:
ld+json
Required parameters:
profile

A single URI identifying the resource as a JSON-LD Frame. A profile does not change the semantics of the resource representation when processed without profile knowledge, so that clients both with and without knowledge of a profiled resource can safely use the same representation.

http://www.w3.org/ns/json-ld#frame
To request or specify a JSON-LD Frame document.

The http://www.w3.org/ns/json-ld#frame `profile` parameter SHOULD be used when serving and requesting a JSON-LD Frame document.

The definition of this parameter is subject to an errantum and will be updated in the next version.

Optional parameters:
None.
Encoding considerations:
See RFC 8259, section 11.
Security considerations:
See RFC 8259, section 12 [[RFC8259]]

Since JSON-LD is intended to be a pure data exchange format for directed graphs, the serialization SHOULD NOT be passed through a code execution mechanism such as JavaScript's eval() function to be parsed. An (invalid) document may contain code that, when executed, could lead to unexpected side effects compromising the security of a system.

When processing JSON-LD documents, links to remote contexts are typically followed automatically, resulting in the transfer of files without the explicit request of the user for each one. If remote contexts are served by third parties, it may allow them to gather usage patterns or similar information leading to privacy concerns. Specific implementations, such as the API defined in the JSON-LD 1.1 Processing Algorithms and API specification [[JSON-LD11-API]], may provide fine-grained mechanisms to control this behavior.

JSON-LD contexts that are loaded from the Web over non-secure connections, such as HTTP, run the risk of being altered by an attacker such that they may modify the JSON-LD active context in a way that could compromise security. It is advised that any application that depends on a remote context for mission critical purposes vet and cache the remote context before allowing the system to use it.

Given that JSON-LD allows the substitution of long IRIs with short terms, JSON-LD documents may expand considerably when processed and, in the worst case, the resulting data might consume all of the recipient's resources. Applications should treat any data with due skepticism.

As JSON-LD places no limits on the IRI schemes that may be used, and vocabulary-relative IRIs use string concatenation rather than IRI resolution, it is possible to construct IRIs that may be used maliciously, if dereferenced.

Interoperability considerations:
Not Applicable
Published specification:
https://www.w3.org/TR/json-ld11-framing
Applications that use this media type:
Any programming environment that requires the exchange of directed graphs. Implementations of JSON-LD have been created for JavaScript, Python, Ruby, PHP, and C++.
Additional information:
Magic number(s):
Not Applicable
File extension(s):
.jsonld
Macintosh file type code(s):
TEXT
Person & email address to contact for further information:
Ivan Herman <ivan@w3.org>
Intended usage:
Common
Restrictions on usage:
None
Author(s):
Manu Sporny, Gregg Kellogg, Markus Lanthaler, Dave Longley
Change controller:
W3C

Fragment identifiers used with application/ld+json are treated as in RDF syntaxes, as per RDF 1.1 Concepts and Abstract Syntax [[RDF11-CONCEPTS]].

Open Issues

The following is a list of issues open at the time of publication.

Allow class-scoped framing.

Several frames in the same frame document?

Reframing Relationships.

Changes since 1.0 Draft of 30 August 2012

Changes since JSON-LD Community Group Final Report

Changes since Candidate Release of 12 December 2019

Changes since Proposed Recommendation Release of 7 May 2020

Changes since Recommendation of 16 July 2020