ORE User Guide - Resource Map Implementation in JSON-LD

2014-08-14

This version:
http://www.openarchives.org/ore/0.9/jsonld
doi:10.5281/zenodo.11293
Latest version:
http://www.openarchives.org/ore/jsonld
Editors
Stian Soiland-Reyes, University of Manchester
Matthew Gamble, University of Manchester
Oscar Corcho, Universidad Politecnica de Madrid
Contributors
Simeon Warner, Cornell University

Abstract

Open Archives Initiative Object Reuse and Exchange (OAI-ORE) defines standards for the description and exchange of aggregations of Web resources. OAI-ORE introduces the notion of a Resource Map, an RDF Graph [RDF Concepts] which describes the Aggregation, the aggregated Resources of which it is composed, and the relationships between them (and/or the relationships between these and other resources).

Since a Resource Map is an RDF Graph, it can be serialized using any RDF syntax. This document outlines the use of one such syntax for the serialization of Resource Maps: JSON-LD [JSON-LD]. Two companion documents ORE RDFa [ORE RDFa] and ORE RDF/XML [ORE RDF/XML] outline the serialization of Resource Maps in RDFa Syntax [RDFa Syntax] and RDF/XML syntax [RDF/XML Syntax] respectively.

This document is intended for implementers who have an understanding of ORE concepts and are responsible for the development of applications which generate or process Resource Maps using JSON-LD. Readers who want a high-level understanding of the motivation for ORE, and of the solution it provides, should read the Primer [ORE Primer]; readers who want further details of the JSON-LD syntax should consult the W3C JSON-LD specification [JSON-LD].

This is one of several documents comprising the OAI-ORE specifications and user guides.

This is a beta specification released for public comment. Please send feedback to the OAI-ORE Google Group.


Table of Contents

1. Introduction
    1.1 Notational Conventions
    1.2 Namespaces
    1.3 Conformance
2. Overview of ORE in JSON-LD syntax
    2.1 ResourceMap, describes, Aggregation
    2.2 isDescribedBy
    2.3 similarTo
    2.4 aggregates
    2.5 isAggregatedBy, isDescribedBy
    2.6 proxies, proxyFor, proxyIn
    2.7 lineage and provenance of proxy
3. ORE JSON-LD context
    3.1 Additional contexts
    3.2 Content of ORE JSON-LD context
4. Complete example
    4.1 Example JSON-LD
    4.2 Example triples
5. ORE JSON-LD frame
    5.1 Example framing
    5.2 Framing proxies
6. References
A. Acknowledgements
B. Change Log


1. Introduction

Open Archives Initiative Object Reuse and Exchange (OAI-ORE) defines standards for the description and exchange of aggregations of web resources. The OAI-ORE Abstract Data Model [ORE Model] introduces the notion of a Resource Map, an RDF Graph [RDF Concepts] which describes the Aggregation, the aggregated Resources of which it is composed, and the relationships between them (and/or the relationships between these and other resources). A Resource Map is an RDF Graph and can thus be serialized using any RDF syntax. This document outlines the use of the JSON-LD syntax for serialization of Resource Maps.

The JSON-LD specification [JSON-LD] describes a format for serialising RDF graphs as JSON [RFC4627]. In short, the JSON-LD format allows the use of JSON Objects (maps/dictionaries) to represent an RDF resource. The JSON-LD reserved key @id defines the IRI for the resource, and @type defines the rdf:type (class of the resource). Other RDF properties are defined using additional keys on the resource, and can point to either other JSON Objects, JSON Lists (multiple property relations) or to plain JSON literals. The JSON-LD @context can define prefixes and short-hand names, thus avoiding the need to use full IRIs for identifying properties and types. This specification includes a ORE JSON-LD context for this purpose.

JSON-LD allows for several equivalent representations of the same graph triples, and a compliant ORE JSON-LD document might therefore not follow the JSON structure exactly as listed in the examples of this document. See the framing section for measures to shape an ORE JSON-LD document into a predictable JSON structure.

1.1 Notational Conventions

The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 [RFC2119].

This specification uses the common term URI to mean both IRI [RFC3987] and URI [RFC3986]. JSON-LD natively supports IRIs without any special measures.

1.2 Namespaces

This specification uses the following namespaces and prefixes:

Prefix Namespace URI Description
ore http://www.openarchives.org/ore/terms/ ORE vocabulary
rdf http://www.w3.org/1999/02/22-rdf-syntax-ns# RDF built-in vocabulary
rdfs http://www.w3.org/2000/01/rdf-schema# RDFS vocabulary
owl http://www.w3.org/2002/07/owl# OWL vocabulary
dcterms http://purl.org/dc/terms/ Dublin Core Terms
dcmitype http://purl.org/dc/dcmitype/ Dublin Core DCMI types
fabio http://purl.org/spar/fabio/ FaBiO, the FRBR-aligned Bibliographic Ontology
foaf http://xmlns.com/foaf/0.1/ FOAF vocabulary
prov http://w3.org/ns/prov#/ PROV ontology
pav http://purl.org/pav/ PAV ontology
schema http://schema.org/ schema.org vocabulary

1.3 Conformance

The Internet Media Type (MIME type) for JSON-LD is application/ld+json. Where JSON-LD is used to provide representations of ORE Resource Maps, that media type SHOULD be used. For backwards compatibility, the JSON-LD specification allows for the alternative content-type of application/json, in which case the JSON-LD context Link header MUST be present.

A consumer of ORE Resource Maps encoded in JSON-LD SHOULD support all of the syntactic conventions defined by JSON-LD. This allowance for different syntactic conventions is supported by conformant JSON-LD parsers [see JSON-LD Community].

2. Overview of ORE in JSON-LD syntax

An ORE Resource Map expressed as a JSON-LD resource MUST be valid JSON [RFC4627], and MUST be valid JSON-LD [JSON-LD].

An ORE JSON-LD resource MUST define a JSON-LD @context, which SHOULD be https://w3id.org/ore/context (see ORE JSON-LD context below).

The @type SHOULD be provided for ORE resources of type Aggregation, ResourceMap, Proxy, and MAY be provided for resources of type AggregatedResource and others.

ResourceMap, describes, Aggregation

The ResourceMap SHOULD be the top-level JSON object (indicating that the JSON-LD document is the resource map), in which case it MUST indicate which Aggregation it describes:

{ "@context": "https://w3id.org/ore/context",
  
  "@type": "ResourceMap",
  "@id": "",
  "describes": {
      "@id": "http://example.com/aggregation-1",
      "@type": "Aggregation"
  }
  
}

The Aggregation MUST have an @id to identify it; this URI SHOULD be absolute. The ResourceMap MAY have an identifier using @id, which MUST be different from the Aggregation URI.

isDescribedBy

The Aggregation MAY list other resource maps it isDescribedBy, which SHOULD be given as a JSON list of URIs:

{ "@context": "https://w3id.org/ore/context",
  "@type": "ResourceMap",
  "describes": {
      "@id": "http://example.com/aggregation-1",
      "@type": "Aggregation",
      
      "isDescribedBy": [
          "http://example.com/aggregation-1.rdf",
          "http://example.com/aggregation-1.jsonld"
      ]
      
  }
}

similarTo

If an Aggregation can be considered similar to another resource, like a journal article identified with a DOI, then this MAY be indicated using similarTo:

{ "@context": "https://w3id.org/ore/context",
  "@type": "ResourceMap",
  "describes": {
      "@id": "http://example.com/aggregation-1",
      "@type": "Aggregation",
      
      "similarTo": "http://dx.doi.org/10.1002/cpe.1594"
      
  }
}

aggregates

All resources aggregated by this Aggregation MUST be listed using aggregates, which SHOULD be given as a JSON list. The list MUST contain either URI strings or JSON Objects, which SHOULD specify their URI with @id:

{ "@context": "https://w3id.org/ore/context",
  "@type": "ResourceMap",
  "describes": {
      "@id": "http://example.com/aggregation-1",
      "@type": "Aggregation",
      
      "aggregates": [
          "http://example.com/document-1",
          { "@id": "http://other.example.org/data-2",
            "@type": "AggregatedResource"
          }
      ]
      
  }
}

Aggregated resources MAY specify their "@type": "AggregatedResource". If a more specific type of the resource is known (e.g. dcmitype:MovingImage or fabio:MagazineNewsItem), it is RECOMMENDED to specify this using @type and the full URI of the class. A JSON List MAY be used to indicate multiple types. Example:

{ "@context": "https://w3id.org/ore/context",
  "@type": "ResourceMap",
  "describes": {
      "@id": "http://example.com/aggregation-1",
      "@type": "Aggregation",
      
      "aggregates": [
          "http://example.com/document-1",
          { "@id": "http://other.example.org/data-2",
            "@type": ["AggregatedResource",
                      "http://purl.org/dc/dcmitype/Dataset",
                      "http://www.w3.org/ns/dcat#Dataset"]
          }
      ]
      
  }
}

Additional descriptions of aggregated resources MAY be provided using other RDF vocabularies following the JSON-LD syntax. The example below shows how to to indicate the provenance of an aggregated resource using PROV-O [PROV-O] and PAV [PAV]. When using third-party vocabularies it may be desirable to add prefixes using additional contexts as a list.

{ "@context": [
    "https://w3id.org/ore/context",
    {
      "foaf": "http://xmlns.com/foaf/0.1/",
      "schema": "http://schema.org/",
      "prov": "http://www.w3.org/ns/prov#",
      "pav": "http://purl.org/pav/"
    }
  ],
  "@type": "ResourceMap",
  "describes": {
      "@id": "http://example.com/aggregation-1",
      "@type": "Aggregation",
      "aggregates": [
          "http://example.com/document-1",
          {  "@id": "http://example.com/blog/",
          
             "@type": "schema:BlogPosting",
             "prov:wasDerivedFrom": {
                 "@id": "http://example.com/document-1"
             },
             "pav:authoredBy": {
                "@id": "http://orcid.org/0000-0001-9842-9718",
                "foaf:name": "Stian Soiland-Reyes"
             }
          
          }
      ]
  }
}

isAggregatedBy, isDescribedBy

If a resource is also part of a different Aggregation, then this can be indicated with isAggregatedBy:

{ "@context": "https://w3id.org/ore/context",
  "@type": "ResourceMap",
  "describes": {
      "@id": "http://example.com/aggregation-1",
      "@type": "Aggregation",
      "aggregates": [
          { "@id": "http://other.example.org/data-2",
          
            "isAggregatedBy": {
                "@id": "http://other.example.org/aggregation-2",
                "@type": "Aggregation"
            }
          
          }
      ]
   }
}

It is NOT RECOMMENDED to detail the aggregates of the other Aggregation, but one MAY use isDescribedBy to indicate its ResourceMap representations.

In the special case of aggregating another Aggregation, that SHOULD be typed as an Aggregation, and there SHOULD be at least one ResourceMap representation indicated with isDescribedBy:

{ "@context": "https://w3id.org/ore/context",
  "@type": "ResourceMap",
  "describes": {
      "@id": "http://example.com/aggregation-1",
      "@type": "Aggregation",
      "aggregates": [
          { "@id": "http://other.example.org/aggregation-2",
          
            "@type": "Aggregation",
            "isDescribedBy": [ "http://other.example.org/aggregation-2.rdf",
                               "http://other.example.org/aggregation-2.jsonld" ]
          
          }
      ]
   }
}

proxies, proxyFor, proxyIn

A Proxy represents an AggregatedResource as it exists in a specific Aggregation, which can be used as a subject in other annotations and aggregations. Proxies SHOULD be provided for each aggregated resource:

{ "@context": "https://w3id.org/ore/context",
  "@type": "ResourceMap",
  "describes": {
      "@id": "http://example.com/aggregation-1",
      "@type": "Aggregation",
      "aggregates": [
          { "@id": "http://example.com/document-1" }
      ],
      
      "proxies": [
              { "@id": "urn:uuid:d4e63599-d28d-4966-8606-dbb985a865f2",
                "@type": "Proxy",
                "proxyFor": "http://example.com/document-1" }
      ]
      
  }
}

The property proxies SHOULD be a JSON List of resources, each of which SHOULD have "@type": "Proxy" and MUST identify the aggregated resource using proxyFor. The resource identified by proxyFor MUST be listed under aggregates.

The proxy MUST be identified with an URI using @id, which MAY be a randomly generated UUID [UUID] using the urn:uuuid: scheme.

Note that, unlike in other serializations of ORE resource maps, the property proxyIn SHOULD NOT be given for proxies listed under proxies (it is already given as proxies is a @reverse property for proxyIn); however in the special case of aggregating a proxy, that MUST specify proxyIn, which MUST be a different Aggregation:

{ "@context": "https://w3id.org/ore/context",
  "@type": "ResourceMap",
  "describes": {
      "@id": "http://example.com/aggregation-1",
      "@type": "Aggregation",
      "aggregates": [
          { "@id": "urn:uuid:09561248-bf55-4c85-930a-9a7a60e81602",

            "@type": "Proxy",
            "proxyFor": "http://example.com/document-1",
            "proxyIn": "http://other.example.org/aggregation-3"

          }
      ]
  }
}

Such "external" proxies MUST NOT be listed under proxies as a proxy can only be proxyFor for a single Aggregation, and an aggregation SHOULD NOT aggregate its own proxies. The proxyIn MAY be expanded to a JSON Object with @id and "@type": "Aggregation" to provide isDescribedBy .

lineage and provenance of proxy

If an aggregated resource was discovered in a different aggregation, this lineage can be described between the corresponding proxies:

{ "@context": "https://w3id.org/ore/context",
  "@type": "ResourceMap",
  "describes": {
      "@id": "http://example.com/aggregation-1",
      "@type": "Aggregation",
      "aggregates": [
          { "@id": "http://example.com/document-1" },
      ],
      "proxies": [
              { "@id": "urn:uuid:d4e63599-d28d-4966-8606-dbb985a865f2",
                "@type": "Proxy",
                "proxyFor": "http://example.com/document-1"
                
                "lineage" {
                    "@id": "urn:uuid:09561248-bf55-4c85-930a-9a7a60e81602",
                    "@type": "Proxy",
                    "proxyFor": "http://example.com/document-1",
                    "proxyIn": "http://other.example.org/aggregation-3"
                }
                
      ]
  }
}

Other kinds of provenance of a proxy (e.g. who aggregated the given resource) MAY be stated using vocabularies like PROV-O and PAV. The example below says that Matthew aggregated document-1 (e.g. created its proxy in this aggregation) on the 17th of May 2014 (without implying that he created document-1):

{ "@context": [
    "https://w3id.org/ore/context",
    {
      "foaf": "http://xmlns.com/foaf/0.1/",
      "prov": "http://www.w3.org/ns/prov#",
      "xsd": "http://www.w3.org/2001/XMLSchema#",
      "prov:generatedAtTime": { "@type": "xsd:dateTime" }
    }
  ],
  "@type": "ResourceMap",
  "describes": {
      "@id": "http://example.com/aggregation-1",
      "@type": "Aggregation",
      "aggregates": [
          "http://example.com/document-1"
      ],
      "proxies": [
                  { "@id": "urn:uuid:d4e63599-d28d-4966-8606-dbb985a865f2",
                    "@type": "Proxy",
                    "proxyFor": "http://example.com/document-1",

                    "prov:attributedTo": {
                        "@id": "http://orcid.org/0000-0003-4913-1485",
                        "foaf:name": "Matthew Gamble"
                    },
                    "prov:generatedAtTime": "2014-05-17T14:00:00Z"

                  }
      ]
  }
}

3. ORE JSON-LD context

A JSON-LD context defines how to understand identifiers in a JSON-LD document. The ORE context thus defines how to interpret documents according to the ORE JSON-LD syntax as defined above. This allows these documents to be processed using JSON-LD tools, for instance to convert to other RDF formats.

The context is available from https://w3id.org/ore/context, from where it SHOULD be included using the @context keyword at the top-level node of ORE JSON-LD documents:

  { "@context": "https://w3id.org/ore/context",
    "@type": "ResourceMap",
    "...": ""
  }

3.1 Additional contexts

In order to facilitate usage of additional RDF vocabularies, one MAY instead specify @context as a JSON List which includes the ORE context and additional contexts as either URIs or JSON objects:

{ "@context": [
    "https://w3id.org/ore/context",
    "http://example.com/other/context",
    {
      "prov": "http://www.w3.org/ns/prov#",
      "xsd": "http://www.w3.org/2001/XMLSchema#",
      "prov:generatedAtTime": { "@type": "xsd:dateTime" }
    }
  ],
  "@type": "ResourceMap",
  "...": ""
}

3.2 Content of ORE JSON-LD context

The content of the ORE JSON-LD context at time of writing is:

{
  "@context" : {
    "Proxy" : {
      "@id" : "http://www.openarchives.org/ore/terms/Proxy"
    },
    "proxyFor" : {
      "@id" : "http://www.openarchives.org/ore/terms/proxyFor",
      "@type" : "@id"
    },
    "lineage" : {
      "@id" : "http://www.openarchives.org/ore/terms/lineage",
      "@type" : "@id"
    },
    "describes" : {
      "@id" : "http://www.openarchives.org/ore/terms/describes",
      "@type" : "@id"
    },
    "AggregatedResource" : {
      "@id" : "http://www.openarchives.org/ore/terms/AggregatedResource"
    },
    "ResourceMap" : {
      "@id" : "http://www.openarchives.org/ore/terms/ResourceMap"
    },
    "similarTo" : {
      "@id" : "http://www.openarchives.org/ore/terms/similarTo",
      "@type" : "@id"
    },
    "Aggregation" : {
      "@id" : "http://www.openarchives.org/ore/terms/Aggregation"
    },
    "isAggregatedBy" : {
      "@id" : "http://www.openarchives.org/ore/terms/isAggregatedBy",
      "@type" : "@id"
    },
    "proxyIn" : {
      "@id" : "http://www.openarchives.org/ore/terms/proxyIn",
      "@type" : "@id"
    },
    "aggregates" : {
      "@id" : "http://www.openarchives.org/ore/terms/aggregates",
      "@type" : "@id"
    },
    "isDescribedBy" : {
      "@id" : "http://www.openarchives.org/ore/terms/isDescribedBy",
      "@type" : "@id"
    },
    "proxies": {
      "@reverse" : "http://www.openarchives.org/ore/terms/proxyIn"
    }
  }
}

4. Complete example

The following complete example shows a ResourceMap describing aggregation-1 containing 4 resources (document-1, data-2, aggregation-3 and a proxy for document-1 within aggregation-3). data-2 is also known to be aggregated by aggregation-2.

The aggregated resource aggregation-3 is itself an aggregation with its own resource maps and proxies, but they are not detailed fully here (except for the aggregated external proxy urn:uuid:095612..).

Finally our aggregation has its own set of identified proxies, one for each aggregated resource. Here, the lineage of data-2's aggregation is shown to be originating from aggregation-2.

4.1 Example JSON-LD

{ "@context": "https://w3id.org/ore/context",
  "@id": "",
  "@type": "ResourceMap",
  "describes": {
      "@id": "http://example.com/aggregation-1",
      "@type": "Aggregation",
      "isDescribedBy": [
          "http://example.com/aggregation-1.rdf",
          "http://example.com/aggregation-1.jsonld"
      ],
      "aggregates": [
          "http://example.com/document-1",
          { "@id": "http://other.example.org/data-2",
            "isAggregatedBy": {
                "@id": "http://other.example.org/aggregation-2",
                "@type": "Aggregation",
                "isDescribedBy": "http://other.example.org/aggregation-2.rdf"
            }
          },
          { "@id": "http://other.example.org/aggregation-3",
            "@type": "Aggregation",
            "isDescribedBy": [ "http://other.example.org/aggregation-3.rdf",
                               "http://other.example.org/aggregation-3.jsonld" ]
          },
          { "@id": "urn:uuid:09561248-bf55-4c85-930a-9a7a60e81602",
            "@type": "Proxy",
            "proxyFor": "http://example.com/document-1",
            "proxyIn": "http://other.example.org/aggregation-3"
          }
      ],
      "proxies": [
              { "@id": "urn:uuid:d4e63599-d28d-4966-8606-dbb985a865f2",
                "@type": "Proxy",
                "proxyFor": "http://example.com/document-1"
              },
              { "@id": "urn:uuid:05bd5e0c-94c7-4856-a53f-7f6cf0756751",
                "@type": "Proxy",
                "proxyFor": "http://other.example.org/data-2",
                "lineage": {
                   "@id": "urn:uuid:360ea070-efee-11e3-ac10-0800200c9a66",
                   "@type": "Proxy",
                   "proxyFor": "http://other.example.org/data-2",
                   "proxyIn": "http://other.example.org/aggregation-2" }
              },
              { "@id": "urn:uuid:c0f5f1ad-5269-4cfc-b9f5-e9621c499f53",
                "@type": "Proxy",
                "proxyFor": "http://other.example.org/aggregation-3"
              },
              { "@id": "urn:uuid:318745e0-5ea4-4a68-8a0a-ab27ab96985a",
                "@type": "Proxy",
                "proxyFor": "urn:uuid:09561248-bf55-4c85-930a-9a7a60e81602"
              }
      ],
      "similarTo": "http://dx.doi.org/10.1002/cpe.1594"
  }
}

4.2 Example triples

If processed with the ORE JSON-LD context and using a JSON-LD library to generate RDF, the following triples are expressed:

<> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.openarchives.org/ore/terms/ResourceMap> .
<> <http://www.openarchives.org/ore/terms/describes> <http://example.com/aggregation-1> .

<http://example.com/aggregation-1> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.openarchives.org/ore/terms/Aggregation> .
<http://example.com/aggregation-1> <http://www.openarchives.org/ore/terms/isDescribedBy> <http://example.com/aggregation-1.jsonld> .
<http://example.com/aggregation-1> <http://www.openarchives.org/ore/terms/isDescribedBy> <http://example.com/aggregation-1.rdf> .
<http://example.com/aggregation-1> <http://www.openarchives.org/ore/terms/similarTo> "http://dx.doi.org/10.1002/cpe.1594" .

<http://example.com/aggregation-1> <http://www.openarchives.org/ore/terms/aggregates> <http://example.com/document-1> .
<http://example.com/aggregation-1> <http://www.openarchives.org/ore/terms/aggregates> <http://other.example.org/aggregation-3> .
<http://example.com/aggregation-1> <http://www.openarchives.org/ore/terms/aggregates> <http://other.example.org/data-2> .
<http://example.com/aggregation-1> <http://www.openarchives.org/ore/terms/aggregates> <urn:uuid:09561248-bf55-4c85-930a-9a7a60e81602> .

<http://other.example.org/data-2> <http://www.openarchives.org/ore/terms/isAggregatedBy> <http://other.example.org/aggregation-2> .

<http://other.example.org/aggregation-2> <http://www.openarchives.org/ore/terms/isDescribedBy> <http://other.example.org/aggregation-2.rdf> .
<http://other.example.org/aggregation-2> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.openarchives.org/ore/terms/Aggregation> .

<http://other.example.org/aggregation-3> <http://www.openarchives.org/ore/terms/isDescribedBy> <http://other.example.org/aggregation-3.jsonld> .
<http://other.example.org/aggregation-3> <http://www.openarchives.org/ore/terms/isDescribedBy> <http://other.example.org/aggregation-3.rdf> .
<http://other.example.org/aggregation-3> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.openarchives.org/ore/terms/Aggregation> .


<urn:uuid:d4e63599-d28d-4966-8606-dbb985a865f2> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.openarchives.org/ore/terms/Proxy> .
<urn:uuid:d4e63599-d28d-4966-8606-dbb985a865f2> <http://www.openarchives.org/ore/terms/proxyFor> <http://example.com/document-1> .
<urn:uuid:d4e63599-d28d-4966-8606-dbb985a865f2> <http://www.openarchives.org/ore/terms/proxyIn> <http://example.com/aggregation-1> .


<urn:uuid:05bd5e0c-94c7-4856-a53f-7f6cf0756751> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.openarchives.org/ore/terms/Proxy> .
<urn:uuid:05bd5e0c-94c7-4856-a53f-7f6cf0756751> <http://www.openarchives.org/ore/terms/proxyFor> <http://other.example.org/data-2> .
<urn:uuid:05bd5e0c-94c7-4856-a53f-7f6cf0756751> <http://www.openarchives.org/ore/terms/proxyIn> <http://example.com/aggregation-1> .
<urn:uuid:05bd5e0c-94c7-4856-a53f-7f6cf0756751> <http://www.openarchives.org/ore/terms/lineage> <urn:uuid:360ea070-efee-11e3-ac10-0800200c9a66> .

<urn:uuid:c0f5f1ad-5269-4cfc-b9f5-e9621c499f53> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.openarchives.org/ore/terms/Proxy> .
<urn:uuid:c0f5f1ad-5269-4cfc-b9f5-e9621c499f53> <http://www.openarchives.org/ore/terms/proxyFor> <http://other.example.org/aggregation-3> .
<urn:uuid:c0f5f1ad-5269-4cfc-b9f5-e9621c499f53> <http://www.openarchives.org/ore/terms/proxyIn> <http://example.com/aggregation-1> .

<urn:uuid:318745e0-5ea4-4a68-8a0a-ab27ab96985a> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.openarchives.org/ore/terms/Proxy> .
<urn:uuid:318745e0-5ea4-4a68-8a0a-ab27ab96985a> <http://www.openarchives.org/ore/terms/proxyFor> <urn:uuid:09561248-bf55-4c85-930a-9a7a60e81602> .
<urn:uuid:318745e0-5ea4-4a68-8a0a-ab27ab96985a> <http://www.openarchives.org/ore/terms/proxyIn> <http://example.com/aggregation-1> .


<urn:uuid:360ea070-efee-11e3-ac10-0800200c9a66> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.openarchives.org/ore/terms/Proxy> .
<urn:uuid:360ea070-efee-11e3-ac10-0800200c9a66> <http://www.openarchives.org/ore/terms/proxyFor> <http://other.example.org/data-2> .
<urn:uuid:360ea070-efee-11e3-ac10-0800200c9a66> <http://www.openarchives.org/ore/terms/proxyIn> <http://other.example.org/aggregation-2> .

<urn:uuid:09561248-bf55-4c85-930a-9a7a60e81602> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.openarchives.org/ore/terms/Proxy> .
<urn:uuid:09561248-bf55-4c85-930a-9a7a60e81602> <http://www.openarchives.org/ore/terms/proxyFor> <http://example.com/document-1> .
<urn:uuid:09561248-bf55-4c85-930a-9a7a60e81602> <http://www.openarchives.org/ore/terms/proxyIn> <http://other.example.org/aggregation-3> .

5. ORE JSON-LD frame

JSON-LD, as all RDF serialization, allow many degrees of freedom for representing the same RDF graph. Thus, an ORE Resource Map could appear in other JSON structures than the one defined in this document. This could particularly be the case if converting an ORE Resource Map to JSON-LD using regular RDF libraries.

By facilitating JSON-LD Framing [JSON-LD Framing] with the ORE JSON-LD Frame, followed by JSON-LD Compaction, a predictable JSON structure is returned that can be used by consumers without requiring any further JSON-LD or RDF knowledge.

Note: At time of writing, JSON-LD Framing a draft specification which is still subject to change. This section is therefore to be considered as experimental. The ORE JSON-LD Frame at https://w3id.org/ore/frame might subsequently be updated independently of this document in order to be compliant with later updates of the JSON-LD Framing specification.

The ORE JSON-LD frame is available at https://w3id.org/ore/frame, which at time of writing is:

 { "@context": "https://w3id.org/ore/context",
   "describes": {
     "@type": "Aggregation",
     "isDescribedBy":  { "@embed": false } ,
     "aggregates":  { "@embed": true }  ,
     "proxies":  { "@embed": true }
   }
 }

5.1 Example framing

For example, say we have a "unstructured" JSON-LD ORE manifest after serializing a Resource Map as triples in JSON-LD:

{
  "@graph": [
    {
      "@id": "http://example.com/aggregation-1",
      "@type": "http://www.openarchives.org/ore/terms/Aggregation",
      "http://www.openarchives.org/ore/terms/aggregates": [
        {
          "@id": "http://example.com/document-1"
        },
        {
          "@id": "http://other.example.org/data-2"
        },
        {
          "@id": "http://other.example.org/aggregation-3"
        },
        {
          "@id": "urn:uuid:09561248-bf55-4c85-930a-9a7a60e81602"
        }
      ],
      "http://www.openarchives.org/ore/terms/isDescribedBy": [
        {
          "@id": "http://example.com/aggregation-1.rdf"
        },
        {
          "@id": "http://example.com/aggregation-1.jsonld"
        }
      ],
      "http://www.openarchives.org/ore/terms/similarTo": {
        "@id": "http://dx.doi.org/10.1002/cpe.1594"
      }
    },
    {
      "@id": "index.html",
      "@type": "http://www.openarchives.org/ore/terms/ResourceMap",
      "http://www.openarchives.org/ore/terms/describes": {
        "@id": "http://example.com/aggregation-1"
      }
    },
    {
      "@id": "http://other.example.org/aggregation-2",
      "@type": "http://www.openarchives.org/ore/terms/Aggregation",
      "http://www.openarchives.org/ore/terms/isDescribedBy": {
        "@id": "http://other.example.org/aggregation-2.rdf"
      }
    },
    {
      "@id": "http://other.example.org/aggregation-3",
      "@type": "http://www.openarchives.org/ore/terms/Aggregation",
      "http://www.openarchives.org/ore/terms/isDescribedBy": [
        {
          "@id": "http://other.example.org/aggregation-3.rdf"
        },
        {
          "@id": "http://other.example.org/aggregation-3.jsonld"
        }
      ]
    },
    {
      "@id": "http://other.example.org/data-2",
      "http://www.openarchives.org/ore/terms/isAggregatedBy": {
        "@id": "http://other.example.org/aggregation-2"
      }
    },
    {
      "@id": "urn:uuid:05bd5e0c-94c7-4856-a53f-7f6cf0756751",
      "@type": "http://www.openarchives.org/ore/terms/Proxy",
      "http://www.openarchives.org/ore/terms/lineage": {
        "@id": "urn:uuid:360ea070-efee-11e3-ac10-0800200c9a66"
      },
      "http://www.openarchives.org/ore/terms/proxyFor": {
        "@id": "http://other.example.org/data-2"
      },
      "http://www.openarchives.org/ore/terms/proxyIn": {
        "@id": "http://example.com/aggregation-1"
      }
    },
    {
      "@id": "urn:uuid:09561248-bf55-4c85-930a-9a7a60e81602",
      "@type": "http://www.openarchives.org/ore/terms/Proxy",
      "http://www.openarchives.org/ore/terms/proxyFor": {
        "@id": "http://example.com/document-1"
      },
      "http://www.openarchives.org/ore/terms/proxyIn": {
        "@id": "http://other.example.org/aggregation-3"
      }
    },
    {
      "@id": "urn:uuid:318745e0-5ea4-4a68-8a0a-ab27ab96985a",
      "@type": "http://www.openarchives.org/ore/terms/Proxy",
      "http://www.openarchives.org/ore/terms/proxyFor": {
        "@id": "urn:uuid:09561248-bf55-4c85-930a-9a7a60e81602"
      },
      "http://www.openarchives.org/ore/terms/proxyIn": {
        "@id": "http://example.com/aggregation-1"
      }
    },
    {
      "@id": "urn:uuid:360ea070-efee-11e3-ac10-0800200c9a66",
      "@type": "http://www.openarchives.org/ore/terms/Proxy",
      "http://www.openarchives.org/ore/terms/proxyFor": {
        "@id": "http://other.example.org/data-2"
      },
      "http://www.openarchives.org/ore/terms/proxyIn": {
        "@id": "http://other.example.org/aggregation-2"
      }
    },
    {
      "@id": "urn:uuid:c0f5f1ad-5269-4cfc-b9f5-e9621c499f53",
      "@type": "http://www.openarchives.org/ore/terms/Proxy",
      "http://www.openarchives.org/ore/terms/proxyFor": {
        "@id": "http://other.example.org/aggregation-3"
      },
      "http://www.openarchives.org/ore/terms/proxyIn": {
        "@id": "http://example.com/aggregation-1"
      }
    },
    {
      "@id": "urn:uuid:d4e63599-d28d-4966-8606-dbb985a865f2",
      "@type": "http://www.openarchives.org/ore/terms/Proxy",
      "http://www.openarchives.org/ore/terms/proxyFor": {
        "@id": "http://example.com/document-1"
      },
      "http://www.openarchives.org/ore/terms/proxyIn": {
        "@id": "http://example.com/aggregation-1"
      }
    }
  ]
}

If we expand this JSON-LD document using https://w3id.org/ore/context, then frame it using https://w3id.org/ore/frame we get the framed JSON:

{
  "@context": "https://w3id.org/ore/context",
  "@graph": [
    {
      "@id": "index.html",
      "@type": "ResourceMap",
      "describes": {
        "@id": "http://example.com/aggregation-1",
        "@type": "Aggregation",
        "aggregates": [
          "http://example.com/document-1",
          {
            "@id": "http://other.example.org/data-2",
            "isAggregatedBy": {
              "@id": "http://other.example.org/aggregation-2",
              "@type": "Aggregation",
              "isDescribedBy": [
                "http://other.example.org/aggregation-2.rdf"
              ]
            }
          },
          {
            "@id": "http://other.example.org/aggregation-3",
            "@type": "Aggregation",
            "isDescribedBy": [
              "http://other.example.org/aggregation-3.rdf",
              "http://other.example.org/aggregation-3.jsonld"
            ]
          },
          {
            "@id": "urn:uuid:09561248-bf55-4c85-930a-9a7a60e81602",
            "@type": "Proxy",
            "proxyFor": "http://example.com/document-1",
            "proxyIn": "http://other.example.org/aggregation-3"
          }
        ],
        "isDescribedBy": [
          "http://example.com/aggregation-1.rdf",
          "http://example.com/aggregation-1.jsonld"
        ],
        "similarTo": "http://dx.doi.org/10.1002/cpe.1594"
      }
    }
  ]
}

Note that JSON-LD Framing always gives a @graph JSON List in case there are several Resource Maps that match the pattern. The properties aggregates and isDescribedBy if present, will after processing always be a JSON list, even if there is only a single resource.

5.2 Framing proxies

Note: @reverse properties like proxies is not at the time of writing commonly supported by JSON-LD Framing processors, and therefore have to be extracted separately using this frame for proxies:

{ "@context": "https://w3id.org/ore/context",

   "@type": "Proxy",
   "proxyFor": {
     "@embed": false
   },
   "proxyIn": {
     "@embed": false
   },
  "lineage": {
    "@embed": false,
    "@omitDefault": true
  }
}

When the above frame is processed against the earlier example it will return a list of all the proxies (including those in other aggregations):

{
  "@context": "https://w3id.org/ore/context",
  "@graph": [
    {
      "@id": "urn:uuid:05bd5e0c-94c7-4856-a53f-7f6cf0756751",
      "@type": "Proxy",
      "lineage": "urn:uuid:360ea070-efee-11e3-ac10-0800200c9a66",
      "proxyFor": "http://other.example.org/data-2",
      "proxyIn": "http://example.com/aggregation-1"
    },
    {
      "@id": "urn:uuid:09561248-bf55-4c85-930a-9a7a60e81602",
      "@type": "Proxy",
      "proxyFor": "http://example.com/document-1",
      "proxyIn": "http://other.example.org/aggregation-3"
    },
    {
      "@id": "urn:uuid:318745e0-5ea4-4a68-8a0a-ab27ab96985a",
      "@type": "Proxy",
      "proxyFor": "urn:uuid:09561248-bf55-4c85-930a-9a7a60e81602",
      "proxyIn": "http://example.com/aggregation-1"
    },
    {
      "@id": "urn:uuid:360ea070-efee-11e3-ac10-0800200c9a66",
      "@type": "Proxy",
      "proxyFor": "http://other.example.org/data-2",
      "proxyIn": "http://other.example.org/aggregation-2"
    },
    {
      "@id": "urn:uuid:c0f5f1ad-5269-4cfc-b9f5-e9621c499f53",
      "@type": "Proxy",
      "proxyFor": "http://other.example.org/aggregation-3",
      "proxyIn": "http://example.com/aggregation-1"
    },
    {
      "@id": "urn:uuid:d4e63599-d28d-4966-8606-dbb985a865f2",
      "@type": "Proxy",
      "proxyFor": "http://example.com/document-1",
      "proxyIn": "http://example.com/aggregation-1"
    }
  ]
}

6. References

[JSON-LD]
JSON-LD 1.0, Manu Sporny, Gregg Kellogg, Markus Lanthaler (editors). W3C Recommendation 16 January 2014.
http://www.w3.org/TR/2014/REC-json-ld-20140116/
Latest version at http://www.w3.org/TR/json-ld/
[JSON-LD Community]
JSON for Linking Data (website), A website run by the JSON for Linking Data W3C Community Group (http://www.w3.org/community/json-ld/).
[JSON-LD Framing]
JSON-LD Framing 1.0, Manu Sporny, Gregg Kellogg, Dave Longley, Markus Lanthaler (editors). Draft Community Group Specification 28 March 2013.
http://json-ld.org/spec/latest/json-ld-framing/
[ORE Model]
ORE Specification - Abstract Data Model, Carl Lagoze, Herbert Van de Sompel, Pete Johnston, Michael Nelson, Robert Sanderson, Simeon Warner. 2008-10-17.
http://www.openarchives.org/ore/1.0/datamodel
Latest version at http://www.openarchives.org/ore/datamodel
[ORE Primer]
ORE User Guide - Primer, Carl Lagoze, Herbert Van de Sompel, Pete Johnston, Michael Nelson, Robert Sanderson, Simeon Warner. 2008-10-17.
http://www.openarchives.org/ore/1.0/primer
Latest version at http://www.openarchives.org/ore/primer
[ORE RDFa]
ORE User Guide - Resource Map Implementation in RDFa, Carl Lagoze, Herbert Van de Sompel, Pete Johnston, Michael Nelson, Robert Sanderson, Simeon Warner. 2008-10-17.
http://www.openarchives.org/ore/1.0/rdfa
Latest version at http://www.openarchives.org/ore/rdfa
[ORE RDFXML]
ORE User Guide - Resource Map Implementation in RDF/XML, C. Lagoze, H. Van de Sompel, P. Johnston, M. Nelson, R. Sanderson, S. Warner, 2008-10-17. Available at http://www.openarchives.org/ore/1.0/rdfxml .
[PAV]
PAV ontology: provenance, authoring and versioning, Paolo Ciccarese, Stian Soiland-Reyes, Khalid Belhajjame, Alasdair J G Gray, Carole Goble, Tim Clark. Journal of Biomedical Semantics 2013, 4:37.
http://purl.org/pav/html doi:10.1186/2041-1480-4-37
[PROV-O]
PROV Ontology, Timothy Lebo, Satya Sahoo, Deborah McGuinness (editors). W3C Recommendation 30 April 2013.
http://www.w3.org/TR/2013/REC-prov-o-20130430/
Latest version at http://www.w3.org/TR/prov-o/
[RDFa Syntax]
RDFa in XHTML: Syntax and Processing. A collection of attributes and processing rules for extending XHTML to support RDF, Ben Adida, Mark Birbeck, Shane McCarron and Steven Pemberton, Editors, W3C Proposed Recommendation 4 September 2008.
Available at http://www.w3.org/TR/2008/PR-rdfa-syntax-20080904/ .
Latest version available at http://www.w3.org/TR/rdfa-syntax/.
[RDF Concepts]
RDF 1.1 Concepts and Abstract Syntax, Richard Cyganiak, David Wood, Markus Lanthaler (editors). W3C Recommendation 25 February 2014.
http://www.w3.org/TR/2014/REC-rdf11-concepts-20140225/
Latest version at http://www.w3.org/TR/rdf-concepts/
[RDFXML]
RDF/XML Syntax Specification (Revised), Dave Beckett and Brian McBrde, Editors. W3C Recommendation, 10 February 2004,
http://www.w3.org/TR/2004/REC-rdf-syntax-grammar-20040210/ .
Latest version available at http://www.w3.org/TR/rdf-syntax-grammar/.
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels, Scott Bradner. IETF RFC 2119, March 1997.
http://www.ietf.org/rfc/rfc2119.txt
[RFC3986]
Uniform Resource Identifier (URI): Generic Syntax, Tim Berners-Lee, Roy T. Fielding, Larry Masinter. IETF RFC 3986, January 2005.
http://www.ietf.org/rfc/rfc3986.txt
[RFC3987]
Internationalized Resource Identifiers (IRIs), Martin J. Dürst, Michel Suignard. IETF RFC 3987, January 2005.
http://www.ietf.org/rfc/rfc3987.txt
[RFC4122]
A Universally Unique IDentifier (UUID) URN Namespace, Paul J. Leach, Micheel Mealling, Rich Salz. IETF RFC 4122, July 2005.
http://www.ietf.org/rfc/rfc4122.txt
[RFC4627]
The application/json Media Type for JavaScript Object Notation (JSON), Douglas Crockford. IETF RFC 4627, July 2006.
http://www.ietf.org/rfc/rfc4627.txt

A. Acknowledgements

The Open Archives Initiative Object Reuse and Exchange specifications are the work of the Open Archives Initiative. Work on this document by Stian Soiland-Reyes was funded by the EU FP7 project BioVeL (FP7 RI-283359). Funding for Open Archives Initiative Object Reuse and Exchange was provided by the Andrew W. Mellon Foundation, Microsoft, the National Science Foundation, and the Coalition for Networked Information.

B. Change Log

Date Editor Description
2014-08-14 simeon Integrate with other OAI-ORE specs, v0.9
2014-08-06 stain Warning about frame spec, scrollbar on long examples
2014-08-03 ocorcho Simplified JSON-LD Frame
2014-07-30 stain Clarified previously draft sections (incl. proxies)
2014-06-11 stain Fixing syntax issues
2014-06-05 stain First draft

See also the current editors' draft. For detailed changelog, see the Github commits.

Creative Commons License
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License.

Use of this page is tracked to collect anonymous traffic data. See OAI privacy policy.