The TREE hypermedia specification

Draft Community Group Report,

More details about this document
This version:
Feedback: with subject line “[TREE] … message topic …” (archives)
Issue Tracking:
Pieter Colpaert


The TREE hypermedia specification enables data publishers and API developers to describe datasets as collections of entities, called “the members”. It then allows to create one or more views of this collection. A view allows organizing the members into multiple pages or nodes, and these nodes are interlinked using relations and/or search forms. This way, a user agent that can interpret the TREE hypermedia controls can find the most efficient way to the members of interest to them.

Status of this document

1. Overview

An overview of the TREE specification with the TREE collection, a reference to the first focus node of its members, and the relations to other nodes from the current node.

The TREE specification introduces these core concepts:

The first step when creating a TREE hypermedia interface is defining a collection of members:

ex:Collection1 a tree:Collection;
            rdfs:label "A Collection of subjects"@en;
            tree:member ex:Subject1, ex:Subject2 .

ex:Subject1 a ex:Subject ;
            rdfs:label "Subject 1" ;
            ex:value 1 .

ex:Subject2 a ex:Subject ;
            rdfs:label "Subject 2" ;
            ex:value 2 .

From the moment this collection of members grows too large for one page, a fragmentation needs to be created in which an initial set of member can be found on an entry node, and more members can be found by interpreting the TREE hypermedia controls. This is illustrated by the next example:


ex:Collection1 a tree:Collection;
            tree:view ex:Node1 ;
            tree:member ex:Subject1, ex:Subject2 .

ex:Node1 a tree:Node ;
        tree:relation ex:R1,ex:R2 .

ex:R1 a tree:GreaterThanOrEqualToRelation ;
    tree:node ex:Node3 ; # This is the URL of another page
    tree:value 3;
    tree:path ex:value .

ex:R1 a tree:LessThanRelation ; # This is very useful for a client that is looking for a value 10 or greater
    tree:node ex:Node3 ; # This is the URL of another page
    tree:value 10;
    tree:remainingItems 7 ;
    tree:path ex:value .

ex:R2 a tree:GreaterThanOrEqualToRelation ;
    tree:node ex:Node4 ; # This is the URL of another page
    tree:value 10;
    tree:remainingItems 10 ;
    tree:path ex:value .

ex:Subject1 a ex:Subject ;
            rdfs:label "Subject 1" ;
            ex:value 1 .

ex:Subject2 a ex:Subject ;
            rdfs:label "Subject 2" ;
            ex:value 2 .
Thanks to the member extraction algorithm, a data publisher can choose to define their members in different ways:
  1. As in the examples above: all quads with the object of the tree:member quads as a subject (and recursively the quads of their blank nodes) are by default included (see also [CBD]), except when they would explicitely not be included in case 3, when the shape would be closed.

  2. Out of band / in band:

    • when no quads of a member have been found, the member will be dereferenced. This allows to publish the member on a separate page.

    • part of the member can be maintained elsewhere when a shape is defined (see 3)

  3. By defining a more complex shape with tree:shape, also nested entities can be included in the member

  4. By putting the triples in a named graph of the object of tree:member, all these triples will be matched.

2. Definitions

A tree:Collection is a set of tree:Members. The set of members MAY be empty.

A tree:Member is a set of (at least one) quad(s) defined by the member extraction algorithm (next subsection).

A tree:Node is a dereferenceable resource containing tree:Relations and a subset of () members of the collection. In a tree:Node, both the set of tree:Relations as the subset of members MAY be empty. The same member MAY be contained in multiple nodes.

A tree:Relation is a function denoting a conditional link to another tree:Node.

A tree:Node, apart from the root node, has exactly one other tree:Node linking into it through one or more relations.

Note: The condition of multiple tree:Relations to the same tree:Node MUST be combined with a logical AND.

A View is a specific set of interlinked tree:Nodes, that together contain all members in a collection. A specific view will adhere to a certain growth or tree balancing strategy. In one View, completeness MUST be guaranteed, unless the View has a retention policy which becomes possible in LDES.

A tree:search form is an IRI template, that when filled out with the right parameters becomes a tree:Node IRI, or when dereferenced will redirect to a tree:Node from which all members in the collection that adhere to the described comparator can be found.

2.1. The member extraction algorithm

The set of quads the are part of the member, are defined by the shape templates algorithm, provided as a separate report to this specification. It is a combination of Concise Bounded Descriptions, named graphs and Shape Templates. The latter uses the sh:NodeShape from the tree:shape property on the collections as an indication of the topology of the member graph.

Note: The way we process SHACL shapes into Shape Template is important to understand in order to know when an HTTP request will be triggered when designing SHACL shapes. A cardinality constraint not being exactly matched or a sh:pattern not being respected will not trigger an HTTP request, and instead just add the invalid quads to the Member. This is a design choice: we only define triggers for HTTP request from the SHACL shape to come to a complete set of quads describing the member the data publisher pointed at using tree:member.

3. Discovery and source selection

TREE tackles discovery and source selection on three levels: i) interface discovery, ii) view discovery, and iii) dataset discovery. Interface discovery discovers what collection the current page is part of, and discovers what the next possible HTTP requests are through relations and search forms. One dataset can have multiple views that can be published across different servers, selecting one for a certain use case is part of the view discovery. Dataset discovery is then selecting a tree:Collection of interest.

3.1. Interface discovery

Interface discovery starts when a URL is provided to a specific tree:Node. A node from which all members of a collection can be discovered (an “entry node”), can be found through a triple stating ex:C1 tree:view ex:N1 with ex:C1 being a tree:Collection and ex:N1 being a tree:Node.

When the current page is a tree:Node, there MUST be a property linking the current page URL to the URI of the tree:Collection. However, not from all tree:Nodes all members can be reached, and therefore 2 other properties can be used: void:subset, or the inverse property, dcterms:isPartOf.

ex:C1 tree:view <> . links the current page to the tree:Collection.

We refer to next chapters for traversing across multiple relations, or for using search forms.

3.2. View discovery

Todo: This will be reworked

Note: How a client picks the right view is use case specific. The tree:ViewDescription’s properties can help in that regards.

In order to prioritize a specific view link, the relations and search forms in the entry nodes can be studied for their relation types, path or remaining items. The class tree:ViewDescription indicates a specific TREE structure on a tree:Collection. Through the property tree:viewDescription a tree:Node can link to an entity that describes the view, and can be reused in data portals as the dcat:DataService.

## What can be found in a tree:Node
ex:N1 a tree:Node ;
  tree:viewDescription ex:View1 .
ex:C1 a tree:Collection ;
  tree:view ex:N1 .

## What can be found on a data portal
ex:C1 a dcat:Dataset .
ex:View1 a tree:ViewDescription, dcat:DataService ;
  dcat:endpointURL ex:N1 ; # The entry point that can be advertised in a data portal
  dcat:servesDataset ex:C1 .

When there is no tree:viewDescription property in this page, a client either already discovered the description of this view in an earlier tree:Node, either the current tree:Node is implicitly the ViewDescription. Therefore, when the property path tree:view → tree:viewDescription does not yield a result, the view properties MUST be extracted from the object of the tree:view triple. A tree:Node can also be double typed as the tree:ViewDescription. A client must thus check for ViewDescriptions on both the current node without the tree:viewDescription qualification, as on the current node with the tree:viewDescription link.

3.3. Dataset discovery

When multiple collections are found by a client, it can choose to prune the collections based on the tree:shape property. Therefore a data publisher SHOULD annotate a tree:Collection instance with a SHACL shape. The tree:shape points to a SHACL description of the shape (sh:NodeShape).

Note: the shape can be a blank node, or a named node on which you should follow your nose when it is defined at a different HTTP URL.

Note: For compatibility with the Solid specifications, a ShEx shape may also be given (see the chapter on compatibility bellow).

4. The tree:Relations

The initial configuration of the tree:Collection and the description of the view is always provided when the view has been discovered, either in a separate document describing the view, either in the entry node itself. The configuration MUST be reused on any subsequent tree:Node.

While discovering and traversing the interface, a client MUST take the descriptions on top of the Node, the View and the Collection with it.

4.1. Traversing relations

A tree:Node element MAY have one or more tree:relation properties. A relation is an entity of the type tree:Relation, and MAY have a more specific type. A tree:Relation MUST have one tree:node object of the type tree:Node. By default, all nodes need to be followed, unless the client is able to select this relation for pruning (see next section).

The tree:Relation’s tree:value SHOULD be set. The object of tree:value SHOULD be accompanied by a data type when it is a literal value.

Every tree:Relation SHOULD have a tree:path, indicating the path from the member to the object on which the tree:Relation applies. For the different ways to express or handle a tree:path, we refer to 2.3.1 in the shacl specification. All possible combinations of e.g., shacl:alternativePath, shacl:inversePath or shacl:inLanguage in the SHACL spec can be used. When shacl:alternativePath is used, the order in the list will define the importance of the order when evaluating the tree:Relation. A wildcard in the path is limited to the tree:shape of the tree:Collection. The result of the evaluation of the tree:path, is the value that must be compared to the tree:value.

Every tree:Relation MAY provide a tree:remainingItems. A client MAY use tree:remainingItems to estimate the completeness of the downloaded elements to the end-user.

Note: When traversing, a client SHOULD keep a list of already visited pages, as despite this being the TREE spec, circular references and back-links are not explicitly prohibited.

A tree:import MAY be defined in the tree:Relation instance. When there is a tree:path defined, and when the relation is flagged interesting to follow, the import link needs to be downloaded in order to find the necessary literals to be compared (it is thus already a tree:ConditionalImport.

Note: An example of a tree:import is given in the repository.

When dereferencing the object of a tree:node triple, the client MUST follow redirects. The URL to be used as the tree:Node URL is the last URL after redirects.

Note: This enables rebalancing search trees.

4.2. Fallbacks

When there is no tree:view triple provided, a client MUST use the tree:Collection from the previous page and still continue extracting members, and extract further relations defined on the current page URL.

When there are no tree:members and/or no tree:Collection defined, then still a tree:Relation can be defined. The tree:path in the tree:Relation then refers to a pattern that can start from every triple in the page.

When no tree:path is defined, the tree:value MUST be compared to all members’ triples that can be compared to the tree:value as defined by the type of the relation (or when no members or collection are defined, on every triple in the page). When due to rdfs:range incompatibility, the object cannot be compared, the object will not be considered for comparison.

Note: This may enable server developers to indicate an index on all literals of the members (e.g., a prefix relation on title, description and body text) without having to indicate all of the alternative paths in the tree:path.

The target object of a tree:path SHOULD be materialized in the current Node document, but when it is not, the object MAY be considered implicit on the condition both tree:path and tree:member are defined. In contrast to sh:path, a tree:path MAY refer to an implicit property and may not be materialized in the current response. This may break SPARQL processors that did not yet come across the object before in their query plan. However, the tree may still be useful for query processors that, for example, prioritize queries according to the user’s location, and first download nodes that are nearby the user. Therefore, the materialized location of the object is not needed. While not recommended, possible heuristics could try to infer the data, could try to fetch it through another tree:Collection, or retrieve it using URI dereferencing.

4.3. Specific relations

When the only type given for a certain Relation is tree:Relation, then the client must dereference all of the nodes. While this may seem useless, it can be used for the same use case as a hydra:PartialCollectionView.

For other types check the chapter on relation types in the vocabulary [](#Relation).

4.3.1. Comparing strings

String values have three specific type of relations: the tree:PrefixRelation, the tree:SubstringRelation and the tree:SuffixRelation.

Note: We experimented with server-chosen locales such that ça suffit can also be found when following a tree:PrefixRelation with a tree:value "c" (which at this moment is not supported). That would require an understanding of locales, and browser/JavaScript support for locales is too low to be useful at this point.

Also the comparator relations such as tree:GreaterThanRelation can be used. The strings MUST then be compared according to case sensitive unicode ordering.

When a tree:path is defined, mind that you also may have to check the language of the element using the property shacl:inLanguage More languages MAY be set. When no language is set, all strings are compared.

Note: If you want to have one resource containing both e and é as a prefix, you will have to create multiple relations to the same tree:Node.

4.3.2. Comparing named nodes

When using comparator relations such as tree:GreaterThanRelation, named nodes must be compared as defined in the ORDER BY section of the SPARQL specification.

4.3.3. Comparing geospatial features

The tree:GeospatiallyContainsRelation is the relation than can be used to express all further members will be contained within a geospatial region defined by the WKT String in the tree:value.

When using tree:GeospatiallyContainsRelation, the tree:path MUST refer to a literal containing a WKT string, such as geosparql:asWKT.

4.3.4. Comparing time literals

When using relations such as tree:LessThanRelation or tree:GreaterThanRelation, the time literals need to be compared according to these 3 possible data types: xsd:date, xsd:dateTime or xsd:dateTimeStamp.

5. Search forms

Searching through a TREE will allow you to immediately jump to the right tree:Node. TREE relies on the Hydra search specification for its search forms. It does however extend Hydra with specific search properties (hydra:IriTemplate) for different types of search forms, and searches starting from a tree:ViewDescription, to which the search form is linked with tree:search. The behaviour of the search form fully depends on the specific property, for which TREE introduces a couple of specific properties:

5.1. Geospatial XYZ tiles search form

Three properties allow to specify a geospatial XYZ tiles template (also known as slippy maps).

  1. tree:longitudeTile describes the X value

  2. tree:latitudeTile descrbes the Y value

  3. tree:zoom describes the zoom level

All properties expect positive integers.

<> a tree:Collection ;
    dcterms:title "A prototype tree:Collection for Linked OpenStreetMap’s roads"@en ;
    tree:view <> .

<> a tree:Node ;
    tree:viewDescription <> .

<> a tree:ViewDescription ;
    tree:search [
        a hydra:IriTemplate ;
        hydra:template "{z}/{x}/{y}" ;
        hydra:variableRepresentation hydra:BasicRepresentation ;
        hydra:mapping [
            a hydra:IriTemplateMapping ;
            hydra:variable "x";
            hydra:property tree:longitudeTile;
            hydra:required true
            a hydra:IriTemplateMapping ;
            hydra:variable "y";
            hydra:property tree:latitudeTile;
            hydra:required true
            a hydra:IriTemplateMapping ;
            hydra:variable "z";
            hydra:property tree:zoom;
            hydra:required true
    ] .

This search form describes a specific search form that uses a quad tree. The zoom level describes the depth, the longitudeTile and latitudeTile describe the x and y index of the fragmentation. (e.g., on zoom level 0, there’s 1 tile, on zoom level 1, there are 4 tiles, etc.).

5.2. Searching through a list of objects ordered by time

Same as the previous example but with the predicate tree:timeQuery expecting an xsd:dateTime. This time however, when the page itself does not exist, a redirect is doing to happen to the page containing the timestamp. A tree:path can indicate the time predicate which is intended.

<> a tree:Collection ;
    dcterms:title "An example collection with a time search view"@en ;
    tree:view <> .

<> a tree:Node ;
    tree:viewDescription <> .

<> a tree:ViewDescription ;
    tree:search [
        a hydra:IriTemplate ;
        hydra:template "{generatedAt}" ;
        hydra:variableRepresentation hydra:BasicRepresentation ;
        hydra:mapping [
            a hydra:IriTemplateMapping ;
            hydra:variable "generatedAt";
            tree:path prov:generatedAtTime;
            hydra:property tree:timeQuery;
            hydra:required true
    ] .

6. Imports

A tree:import can be defined on multiple levels. When defined as part of a tree:Node, this document always needs to be fetched when processing this Node. When defined as part of the tree:Relation, one MUST fetch the import when the relation needs to be correctly evaluated (e.g., the resulting page contains elements without materialized WKT strings, which however can be fetched from the import). When importing a file, no hypermedia relations will be followed from that import in order to get more data.

A tree:importStream can also be defined for providing a pubsub interface for subscribing to real-time updates. The object SHOULD be a [websockets] or Server-Sent Events ([eventsource]).

Instead of tree:import, one can also use tree:conditionalImport which links to an object of the type tree:ConditionalImport with these properties:

Note: imports are powerful to keep recurring objects in a separate, more cacheable, resource.

No hypermedia controls in the body MUST be interpreted in the imported resource and the object must be fully contained within that information resource.

On the resources to import, Memento [RFC7089] controls MAY be provided for historic versions.

7. Compatibility

7.1. DCAT

[VOCAB-DCAT-2] is the standard for Open Data Portals by W3C. In order to find TREE compliant datasets in data portals, there SHOULD be a dcat:endpointDescription from the dcat:DataService to the entrypoint where the tree:Collections and the tree:ViewDescriptions are listed. Furthermore, there SHOULD be a dct:conformsTo this URI:

7.2. Hydra

A tree:Collection is compatible with the Hydra Collections specification. However, instead of hydra:view, we use tree:view and do not link to a hydra:PartialCollectionView but to a tree:Node. A hydra:Collection can thus also be extended with a tree:shape and tree:view. When this is done, also hydra:member can be used instead of tree:member.

hydra:totalItems can be used to indicate the total amount of elements in the collection. Hydra paging controls such as hydra:next and hydra:previous are semantically equivalent to a tree:Relation element that only contains a tree:node property.

7.3. Activity Streams 2.0

A tree:Collection is also compatible with [activitystreams-core]’s specification of paged collections. Instead of dcterms:isPartOf, also as:partOf can be used to indicate that the current page is part of the full collection. While Hydra and TREE link to the members of the collection by using the specific collection as a subject, Activity Streams 2.0 (AS) indicates a member starting from the page URL. Therefore, when using AS collections, a client implementation should gather the members from the tree:Node or as:CollectionPage instead.

as:totalItems can be used to indicate the total amount of elements in the collection.

AS paging controls such as as:nextand as:previous are semantically equivalent to a tree:Relation element that only contains a tree:node property.

7.4. LDP Containers

In [LDP], the tree:view can be applied on top of the ldp:Container instance. Members can be found through ldp:contains, and/or through the indirect ldp:membershipResource and ldp:hasMemberRelation or ldp:isMemberOfRelation construct.

If this container is paged by the [ldp-paging] (chapter 7) spec, then this MUST be ignored.

If there is an ordering, this MUST be ignored by TREE clients (the relations contain all necessary information for pruning).

7.5. Shape trees

The Shape Trees specification is specifically built to work within existing ecosystems. As it was conceived to interoperate with LDP, the term Container in the Shape Trees spec can also be interpreted as a tree:Collection. Shape Trees can help in the source selection of what specific tree:Collection to pick for your goal, and may add hierarchies to a set of tree:Collections. A client MAY infer a tree:shape of the collection through the st:validatedBy property of the Shapes Tree.

An example of a collection using Shape Tree terms. In this example a sensor with some observations is validated by using a Shape Expressions (ShEx) file.

@prefix sosa: <> .
@prefix om: <> .
@prefix ldp: <> .

<2021.ttl#Collection> a ldp:Container; 
    st:validatedBy <Sensor.shex#Sensor>;
    tree:member <sensor1>, <sensor2> .

    a sosa:Sensor;
    sosa:observes om:Temperature .

    a sosa:Observation;
    sosa:observedProperty om:Temperature;
    sosa:madeBySensor <sensor1>;
    sosa:hasResult <result1>;
    sosa:resultTime "2020-08-25T07:05:31Z"^^xsd:dateTime .

<result1> a om:Measure; 
    om:hasValue "22"^^xsd:float; 
    om:hasUnit om:degreeCelsius .

    a sosa:Observation;
    sosa:observedProperty om:Temperature;
    sosa:madeBySensor <sensor1>;
    sosa:hasResult <result2>;
    sosa:resultTime "2020-08-25T07:05:32Z"^^xsd:dateTime .

<result2> a om:Measure; 
    om:hasValue "22"^^xsd:float; 
    om:hasUnit om:degreeCelsius .

    a sosa:Sensor;
    sosa:observes om:Temperature .

And its corresponding ShEx file (called Sensor.shex)

PREFIX sosa: <>
PREFIX xsd: <>
PREFIX om: <>
PREFIX rdfs: <>

<#Sensor> {
    a [sosa:Sensor] ;
    sosa:observes [om:Temperature]  ; 
    sosa:madeObservation @<#TemperatureObservation> * 

<#TemperatureObservation> {
    a [sosa:Observation] ;
    sosa:resultTime xsd:dateTime ;
    sosa:madeBySensor @<#Sensor> ? ;
    sosa:observedProperty [om:Temperature];
    sosa:hasResult @<#TemperatureResult> 

<#TemperatureResult> { 
    a [om:Measure];
    om:hasValue xsd:float ;
    om:hasUnit [om:degreeCelsius]

8. Vocabulary



@prefix tree: <>.
@prefix hydra: <>.
@prefix rdf: <>.
@prefix sh: <> .
@prefix xsd: <> .

8.1. Classes

8.1.1. tree:Collection

A collection has members that may adhere to a certain shape.

8.1.2. tree:Node

A tree:Node is a node that may contain links to other dereferenceable resources that lead to a full overview of a tree:Collection.

8.1.3. tree:Relation

An entity that describes a relation between two tree:Nodes.

The tree:Relation has specific sub-classes that implement a more specific type between the values. These types are described in the ontology (all classes are rdf:subClassOf tree:Relation):

8.1.4. tree:ConditionalImport

A class to import a file or a stream based on a tree:path of properties. This way it can import the necessary data for complying to the SHACL shape, or evaluating a relation type.

8.1.5. tree:ViewDescription

Describes a specific TREE structure on top of the tree:Collection.

8.2. Properties

8.2.1. tree:relation

Links a node to a relation

Domain: tree:Node

Range: tree:Relation

8.2.2. tree:remainingItems

Remaining number of items of this node, the items in its children included.

Domain: tree:Relation

Range: xsd:integer

8.2.3. tree:node

The URL to be derefenced when this relation cannot be pruned.

Domain: tree:Relation

Range: tree:Node

8.2.4. tree:value

The contextual value of this node: may contain e.g., a WKT-string with the bound of a rectangle, may contain a string, an integer, or even link to another resource where clear comparison rules apply.

Domain: tree:Relation

8.2.5. tree:path

A property path, as defined by SHACL, that indicates what resource the tree:value affects.

See [](#relations)

Domain: tree:Relation

8.2.6. tree:view

Links the collection to the current tree:Node.

Domain: tree:Collection

Range: tree:Node

Links a tree:Node to a hydra:IriTemplate. The search form will search the remaining items of the node.

Domain: tree:Node

Range: hydra:IriTemplate

8.2.8. tree:shape

The SHACL shape the members of the collection adhere to.

Domain: tree:Collection

Range: sh:NodeShape

8.2.9. tree:member

Links to the collection’s items that are the sh:targetNodes of the SHACL shape defined with tree:shape.

Domain: tree:Collection

8.2.10. tree:import

Imports a document containing triples needed for complying to the SHACL shape, or for evaluating the relation.

8.2.11. tree:conditionalImport

Imports a document only when the client is interesting in a specific tree:path.

8.2.12. tree:zoom

A search form parameter: the zoom level of the tile cfr. OSM convention.

As defined by Slippy Map Tilenames in OpenStreetMap

8.2.13. tree:longitudeTile

A search form parameter: the X tile number from longitude cfr. OSM convention.

As defined by Slippy Map Tilenames in OpenStreetMap

8.2.14. tree:latitudeTile

A search form parameter: the Y tile number from latitude cfr. OSM convention.

As defined by Slippy Map Tilenames in OpenStreetMap

8.2.15. tree:timeQuery

A search form parameter: accompagnied by a tree:path, it indicates the property on which a time search can be done

8.2.16. tree:viewDescription

Links together a tree:Node with its description of this TREE structure.

Domain: tree:Node

Range: tree:ViewDescription


Document conventions

Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.

All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

Examples in this specification are introduced with the words “for example” or are set apart from the normative text with class="example", like this:

This is an example of an informative example.

Informative notes begin with the word “Note” and are set apart from the normative text with class="note", like this:

Note, this is an informative note.


Normative References

James Snell; Evan Prodromou. Activity Streams 2.0. URL:
Patrick Stickler, Nokia. CBD - Concise Bounded Description. 3 June 2005. W3C Member Submission. URL:
Ian Hickson. Server-Sent Events. URL:
Steve Speicher; John Arwe; Ashok Malhotra. Linked Data Platform 1.0. URL:
Steve Speicher; John Arwe; Ashok Malhotra. Linked Data Platform Paging 1.0. URL:
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL:
H. Van de Sompel; M. Nelson; R. Sanderson. HTTP Framework for Time-Based Access to Resource States -- Memento. December 2013. Informational. URL:
Holger Knublauch; Dimitris Kontokostas. Shapes Constraint Language (SHACL). URL:
Riccardo Albertoni; et al. Data Catalog Vocabulary (DCAT) - Version 2. URL:
Simon Cox; et al. Data Catalog Vocabulary (DCAT) - Version 3. URL:
Adam Rice. WebSockets Standard. Living Standard. URL: