This section is non-normative.

JSON-LD has a number of features that provide functionality above and beyond the core functionality described above. JSON can be used to express data using such structures, and the features described in this section can be used to interpret a variety of different JSON structures as Linked Data. A JSON-LD processor will make use of provided and embedded contexts to interpret property values in a number of different idiomatic ways.

JSON-LD serializes directed graphs . That means that every property points from a node to another node or value . However, in some cases, it is desirable to serialize in the reverse direction, as detailed in § 4.8 Reverse Properties .

Another common idiom in JSON is to use an intermediate object to represent property values via indexing. JSON-LD allows data to be indexed in a number of different ways, as detailed in § 4.6 Indexed Values .

A common idiom found in JSON usage is objects being specified as the value of other objects, called object embedding in JSON-LD; for example, a friend specified as an object value of a Person:

In this case, a document residing at http://manu.sporny.org/about may contain the example above, and reference another document at https://greggkellogg.net/foaf which could include a similar representation.

Linked Data is all about describing the relationships between different resources. Sometimes these relationships are between resources defined in different documents described on the web, sometimes the resources are described within the same document.

Another JSON idiom often found in APIs is to use an intermediate object to group together related properties of an object; in JSON-LD these are referred to as nested properties and are described in § 4.4 Nested Properties .

In JSON, a property with an array value implies an implicit order; arrays in JSON-LD do not convey any ordering of the contained elements by default, unless defined using embedded structures or through a context definition. See § 4.3 Value Ordering for a further discussion.

One pattern in JSON is for the value of a property to be a string. Often times, this string actually represents some other typed value, for example an IRI , a date, or a string in some specific language. See § 4.2 Describing Values for details on how to describe such value typing.

The following sections describe such advanced functionality in more detail.

4.1 Advanced Context Usage

This section is non-normative.

Section § 3.1 The Context introduced the basics of what makes JSON-LD work. This section expands on the basic principles of the context and demonstrates how more advanced use cases can be achieved using JSON-LD.

In general, contexts may be used any time a map is defined. The only time that one cannot express a context is as a direct child of another context definition (other than as part of an expanded term definition). For example, a JSON-LD document may have the form of an array composed of one or more node objects, which use a context definition in each top-level node object:

Example 19 : Using multiple contexts Compacted (Input) Expanded (Result) Statements Turtle Open in playground [ { "@context": "https://json-ld.org/contexts/person.jsonld", "name": "Manu Sporny", "homepage": "http://manu.sporny.org/", "depiction": "http://twitter.com/account/profile_image/manusporny" }, { "@context": "https://json-ld.org/contexts/place.jsonld", "name": "The Empire State Building", "description": "The Empire State Building is a 102-story landmark in New York City.", "geo": { "latitude": "40.75", "longitude": "73.98" } } ] [{ "http://xmlns.com/foaf/0.1/name": [{"@value": "Manu Sporny"}], "http://xmlns.com/foaf/0.1/homepage": [{"@id": "http://manu.sporny.org/"}], "http://xmlns.com/foaf/0.1/depiction": [{"@id": "http://twitter.com/account/profile_image/manusporny"}] }, { "http://purl.org/dc/terms/title": [{"@value": "The Empire State Building"}], "http://purl.org/dc/terms/description": [{ "@value": "The Empire State Building is a 102-story landmark in New York City." }], "http://schema.org/geo": [{ "http://www.w3.org/2003/01/geo/wgs84_pos#lat": [{ "@type": "http://www.w3.org/2001/XMLSchema#decimal", "@value": "40.75" }], "http://www.w3.org/2003/01/geo/wgs84_pos#long": [{ "@type": "http://www.w3.org/2001/XMLSchema#decimal", "@value": "73.98" }] }] }] Subject Property Value Value Type _:b0 foaf:name Manu Sporny _:b0 foaf:homepage http://manu.sporny.org/ _:b0 foaf:depiction http://twitter.com/account/profile_image/manusporny _:b1 dcterms:title The Empire State Building _:b1 dcterms:description The Empire State Building is a 102-story landmark in New York City. _:b2 geo:lat 40.75 xsd:decimal _:b2 geo:long 73.98 xsd:decimal _:b1 schema:geo _:b2 @prefix dcterms: <http://purl.org/dc/terms/> . @prefix foaf: <http://xmlns.com/foaf/0.1/> . @prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> . @prefix schema: <http://schema.org/> . @prefix xsd: <http://www.w3.org/2001/XMLSchema#> . [ foaf:name "Manu Sporny"; foaf:homepage <http://manu.sporny.org/>; foaf:depiction <http://twitter.com/account/profile_image/manusporny> ] . [ dcterms:title "The Empire State Building"; dcterms:description "The Empire State Building is a 102-story landmark in New York City."; schema:geo [ geo:lat 40.75; geo:long 73.98 ] ] .

The outer array is standard for a document in expanded document form and flattened document form, and may be necessary when describing a disconnected graph, where nodes may not reference each other. In such cases, using a top-level map with a @graph property can be useful for saving the repetition of @context . See § 4.5 Embedding for more.

Example 20 : Describing disconnected nodes with @graph Compacted (Input) Expanded (Result) Statements Turtle Open in playground { "@context": [ "https://json-ld.org/contexts/person.jsonld", "https://json-ld.org/contexts/place.jsonld", {"title": "http://purl.org/dc/terms/title"} ], "@graph": [ { "http://xmlns.com/foaf/0.1/name": "Manu Sporny", "homepage": "http://manu.sporny.org/", "depiction": "http://twitter.com/account/profile_image/manusporny" }, { "title": "The Empire State Building", "description": "The Empire State Building is a 102-story landmark in New York City.", "geo": { "latitude": "40.75", "longitude": "73.98" } } ] } [{ "http://xmlns.com/foaf/0.1/name": [{"@value": "Manu Sporny"}], "http://xmlns.com/foaf/0.1/homepage": [{"@id": "http://manu.sporny.org/"}], "http://xmlns.com/foaf/0.1/depiction": [{"@id": "http://twitter.com/account/profile_image/manusporny"}] }, { "http://purl.org/dc/terms/title": [{"@value": "The Empire State Building"}], "http://purl.org/dc/terms/description": [{ "@value": "The Empire State Building is a 102-story landmark in New York City." }], "http://schema.org/geo": [{ "http://www.w3.org/2003/01/geo/wgs84_pos#lat": [{ "@type": "http://www.w3.org/2001/XMLSchema#decimal", "@value": "40.75" }], "http://www.w3.org/2003/01/geo/wgs84_pos#long": [{ "@type": "http://www.w3.org/2001/XMLSchema#decimal", "@value": "73.98" }] }] }] Subject Property Value Value Type _:b0 foaf:name Manu Sporny _:b0 foaf:homepage http://manu.sporny.org/ _:b0 foaf:depiction http://twitter.com/account/profile_image/manusporny _:b1 dcterms:title The Empire State Building _:b1 dcterms:description The Empire State Building is a 102-story landmark in New York City. _:b2 geo:lat 40.75 xsd:decimal _:b2 geo:long 73.98 xsd:decimal _:b1 schema:geo _:b2 @prefix dcterms: <http://purl.org/dc/terms/> . @prefix foaf: <http://xmlns.com/foaf/0.1/> . @prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> . @prefix schema: <http://schema.org/> . @prefix xsd: <http://www.w3.org/2001/XMLSchema#> . [ foaf:name "Manu Sporny"; foaf:homepage <http://manu.sporny.org/>; foaf:depiction <http://twitter.com/account/profile_image/manusporny> ] . [ dcterms:title "The Empire State Building"; dcterms:description "The Empire State Building is a 102-story landmark in New York City."; schema:geo [ geo:lat 40.75; geo:long 73.98 ] ] .

Duplicate context terms are overridden using a most-recently-defined-wins mechanism.

Example 21 : Embedded contexts within node objects Compacted (Input) Expanded (Result) Statements Turtle Open in playground { "@context": { "name": "http://example.com/person#name", "details": "http://example.com/person#details" } , " name ": "Markus Lanthaler", "details": { "@context": { "name": "http://example.com/organization#name" } , " name ": "Graz University of Technology" } } [{ "http://example.com/person#details": [{ "http://example.com/organization#name": [{ "@value": "Graz University of Technology" }] }], "http://example.com/person#name": [{"@value": "Markus Lanthaler"}] }] Subject Property Value _:b1 http://example.com/organization#name Graz University of Technology _:b0 http://example.com/person#details _:b1 _:b0 http://example.com/person#name Markus Lanthaler @prefix person: <http://example.com/person#> . @prefix org: <http://example.com/organization#> . [ person:name "Markus Lanthaler"; person:details [org:name "Graz University of Technology"] ] .

In the example above, the name term is overridden in the more deeply nested details structure, which uses its own embedded context. Note that this is rarely a good authoring practice and is typically used when working with legacy applications that depend on a specific structure of the map. If a term is redefined within a context, all previous rules associated with the previous definition are removed. If a term is redefined to null , the term is effectively removed from the list of terms defined in the active context.

Multiple contexts may be combined using an array, which is processed in order. The set of contexts defined within a specific map are referred to as local contexts. The active context refers to the accumulation of local contexts that are in scope at a specific point within the document. Setting a local context to null effectively resets the active context to an empty context, without term definitions, default language, or other things defined within previous contexts. The following example specifies an external context and then layers an embedded context on top of the external context:

In JSON-LD 1.1, there are other mechanisms for introducing contexts, including scoped contexts and imported contexts, and there are new ways of protecting term definitions, so there are cases where the last defined inline context is not necessarily one which defines the scope of terms. See § 4.1.8 Scoped Contexts, § 4.1.9 Context Propagation, § 4.1.10 Imported Contexts, and § 4.1.11 Protected Term Definitions for further information.

Example 22 : Combining external and local contexts Compacted (Input) Expanded (Result) Statements Turtle Open in playground { "@context": [ "https://json-ld.org/contexts/person.jsonld", { "pic": { "@id": "http://xmlns.com/foaf/0.1/depiction", "@type": "@id" } } ], "name": "Manu Sporny", "homepage": "http://manu.sporny.org/", "pic": "http://twitter.com/account/profile_image/manusporny" } [{ "http://xmlns.com/foaf/0.1/name": [{"@value": "Manu Sporny"}], "http://xmlns.com/foaf/0.1/homepage": [{"@id": "http://manu.sporny.org/"}], "http://xmlns.com/foaf/0.1/depiction": [{ "@id": "http://twitter.com/account/profile_image/manusporny" }] }] Subject Property Value Value Type _:b0 foaf:name Manu Sporny _:b0 foaf:homepage http://manu.sporny.org/ IRI _:b0 foaf:depiction http://twitter.com/account/profile_image/manusporny IRI @prefix foaf: <http://xmlns.com/foaf/0.1/> . [ foaf:name "Manu Sporny"; foaf:homepage <http://manu.sporny.org/>; foaf:depiction <http://twitter.com/account/profile_image/manusporny> ] .

Note When possible, the context definition should be put at the top of a JSON-LD document. This makes the document easier to read and might make streaming parsers more efficient. Documents that do not have the context at the top are still conformant JSON-LD.

Note To avoid forward-compatibility issues, terms starting with an @ character followed exclusively by one or more ALPHA characters (see [ RFC5234 ]) are to be avoided as they might be used as keyword in future versions of JSON-LD. Terms starting with an @ character that are not JSON-LD 1.1 keywords are treated as any other term, i.e., they are ignored unless mapped to an IRI . Furthermore, the use of empty terms ( "" ) is not allowed as not all programming languages are able to handle empty JSON keys.

4.1.1 JSON-LD 1.1 Processing Mode This section is non-normative. New features defined in JSON-LD 1.1 are available unless the processing mode is set to json-ld-1.0 . This may be set through an API option. The processing mode may be explicitly set to json-ld-1.1 using the @version entry in a context set to the value 1.1 as a number, or through an API option. Explicitly setting the processing mode to json-ld-1.1 will prohibit JSON-LD 1.0 processors from incorrectly processing a JSON-LD 1.1 document. Example 23 : Setting @version in context { "@context": { "@version": 1.1 } } The first context encountered when processing a document which contains @version determines the processing mode , unless it is defined explicitly through an API option. This means that if "@version": 1.1 is encountered after processing a context without @version , the former will be interpreted as having had "@version": 1.1 defined within it. Note Setting the processing mode explicitly to json-ld-1.1 is RECOMMENDED to prevent a JSON-LD 1.0 processor from incorrectly processing a JSON-LD 1.1 document and producing different results.

4.1.9 Context Propagation This section is non-normative. Once introduced, contexts remain in effect until a subsequent context removes it by setting @context to null , or by redefining terms, with the exception of type-scoped contexts, which limit the effect of that context until the next node object is entered. This behavior can be changed using the @propagate keyword. The following example illustrates how terms defined in a context with @propagate set to false are effectively removed when descending into new node object. Example 49 : Marking a context to not propagate Compacted (Input) Expanded (Result) Statements Turtle Open in playground { "@context": { "@version": 1.1, "term": { "@id": "http://example.org/original", "@context": { "@propagate": false, "term": "http://example.org/non-propagated-term" } } }, "term": { "term": { "term": "This term is from the first context" } } } [{ "http://example.org/original": [{ "http://example.org/non-propagated-term": [{ "http://example.org/original": [ {"@value": "This term is from the first context"} ] }] }] }] Subject Property Value _:b2 http://example.org/original This term is from the first context _:b1 http://example.org/non-propagated-term _:b2 _:b0 http://example.org/original _:b1 @prefix ex: <http://example.org/> . [ ex:original [ ex:non-propagated-term [ ex:original "This term is from the first context" ] ] ] . Note Contexts included within an array must all have the same value for @propagate due to the way that rollback is defined in JSON-LD 1.1 Processing Algorithms and API .

4.1.10 Imported Contexts This section is non-normative. JSON-LD 1.0 included mechanisms for modifying the context that is in effect. This included the capability to load and process a remote context and then apply further changes to it via new contexts. However, with the introduction of JSON-LD 1.1, it is also desirable to be able to load a remote context, in particular an existing JSON-LD 1.0 context, and apply JSON-LD 1.1 features to it prior to processing. By using the @import keyword in a context, another remote context, referred to as an imported context, can be loaded and modified prior to processing. The modifications are expressed in the context that includes the @import keyword, referred to as the wrapping context. Once an imported context is loaded, the contents of the wrapping context are merged into it prior to processing. The merge operation will cause each key-value pair in the wrapping context to be added to the loaded imported context, with the wrapping context key-value pairs taking precedence. By enabling existing contexts to be reused and edited inline prior to processing, context-wide keywords can be applied to adjust all term definitions in the imported context. Similarly, term definitions can be replaced prior to processing, enabling adjustments that, for instance, ensure term definitions match previously protected terms or that they include additional type coercion information. The following examples illustrate how @import can be used to express a type-scoped context that loads an imported context and sets @propagate to true , as a technique for making other similar modifications. Suppose there was a context that could be referenced remotely via the URL https://json-ld.org/contexts/remote-context.jsonld : Example 50 : A remote context to be imported in a type-scoped context { "@context": { "Type1": "http://example.com/vocab/Type1", "Type2": "http://example.com/vocab/Type2", "term1": "http://example.com/vocab#term1", "term2": "http://example.com/vocab#term2" } } A wrapping context could be used to source it and modify it: Example 51 : Sourcing a context in a type-scoped context and setting it to propagate { "@context": { "@version": 1.1, "MyType": { "@id": "http://example.com/vocab#MyType", "@context": { "@version": 1.1, "@import": "https://json-ld.org/contexts/remote-context.jsonld", "@propagate": true } } } } The effect would be the same as if the entire imported context had been copied into the type-scoped context: Example 52 : Result of sourcing a context in a type-scoped context and setting it to propagate { "@context": { "@version": 1.1, "MyType": { "@id": "http://example.com/vocab#MyType", "@context": { "@version": 1.1, "Type1": "http://example.com/vocab/Type1", "Type2": "http://example.com/vocab/Type2", "term1": "http://example.com/vocab#term1", "term2": "http://example.com/vocab#term2", "@propagate": true } } } } Similarly, the wrapping context may replace term definitions or set other context-wide keywords that may affect how the imported context term definitions will be processed: Example 53 : Sourcing a context to modify @vocab and a term definition { "@context": { "@version": 1.1, "@import": "https://json-ld.org/contexts/remote-context.jsonld", "@vocab": "http://example.org/vocab#", "term1": { "@id": "http://example.org/vocab#term1", "@type": "http://www.w3.org/2001/XMLSchema#integer" } } } Again, the effect would be the same as if the entire imported context had been copied into the context: Example 54 : Result of sourcing a context to modify @vocab and a term definition { "@context": { "@version": 1.1, "Type1": "http://example.com/vocab/Type1", "Type2": "http://example.com/vocab/Type2", "term1": { "@id": "http://example.org/vocab#term1", "@type": "http://www.w3.org/2001/XMLSchema#integer" }, "term2": "http://example.com/vocab#term2", "@vocab": "http://example.org/vocab#" } } The result of loading imported contexts must be context definition, not an IRI or an array. Additionally, the imported context cannot include an @import entry.