fils/oihBook huggingface dataset:
JSON-LD Foundation#
Introduction#
JSON-LD is a way of encoding Linked Data in JSON, the popular data interchange
format used by many web APIs. Linked Data is a method of representing information
on the web in a way that allows it to be linked and interconnected with other data.
This allows data from different sources to be connected and used together in new
and powerful ways. JSON-LD uses a standardized syntax to represent Linked Data,
making it easier to integrate with other systems and tools. It is often used to
add structured data to web pages, making it easier for search engines and other
applications to understand and process the information on the page.
This document provide a very brief introduction to the JSON-LD serialization format.
The JSON-LD website has some detailed material and videos in
their documentation section.
The material here is just a brief introduction.   For this page we will be using
a simplified version of a CreativeWork document. All the types used by OIH are defined
by Schema.org types.  In this case it is CreativeWork.
At the Schema.org site you will find extensive details on what the various types mean and
the full range of their properties. For OIH we are defining only a few of these properties
as of interest in the Thematic section.  You are free to use additional
properties to describe your resources.  It will not cause any issues, however, the OIH interfaces
may not leverage them.  However, if you feel others would, or you use them yourself, it’s encouraged
to add them.
We will use the following simple JSON-LD document to show the various features of the format.
 1{
 2    "@context": {
 3        "@vocab": "https://schema.org/"
 4    },
 5    "@type": "CreativeWork",
 6    "@id": "https://example.org/id/XYZ",
 7    "name": "Name or title of the document",
 8    "description": "Description of the creative work to aid in searching",
 9    "url":  "https://www.sample-data-repository.org/creativework/report.pdf"
10}
import json
from pyld import jsonld
import os, sys
currentdir = os.path.dirname(os.path.abspath(''))
sys.path.insert(0, currentdir)
from lib import jbutils
with open("../../../odis-in/dataGraphs/foundation/graphs/simple.json") as dgraph:
    doc = json.load(dgraph)
context = {
    "@vocab": "https://schema.org/",
}
compacted = jsonld.compact(doc, context)
jbutils.show_graph(compacted)
compacted = jsonld.compact(doc, context)
jbutils.show_graph(compacted)
Note
A small note on nomenclature. In Schema.org, as in ontologies, the class or type
names of Things will be uppercase.  So, for example, in the above JSON-LD data graph,
this is describing a resource of type CreativeWork.   So the type CreativeWork will
start with an uppercase letter.  The property name is a property of the type and
properties like this will be lowercase.
The Context#
The context is where the terms used in a document are connected to definitions and identifiers for them.
If you wish to dive into the details of the context check out the
W3 JSON-LD 1.1 Recommendations Context section.
The context part of this document is highlighted below.
 1{
 2    "@context": {
1{
 2    "@context": {
 3        "@vocab": "https://schema.org/"
 4    },
 5    "@type": "CreativeWork",
 6    "@id": "https://example.org/id/XYZ",
 7    "name": "Name or title of the document",
 8    "description": "Description of the creative work to aid in searching",
 9    "url":  "https://www.sample-data-repository.org/creativework/report.pdf"
10}
Note
This @context section will be the same for all
the documents described in OIH documentation with the exception of the spatial patterns.
As justed noted, for the spatial patterns we add in the OGC context
to all us to use terms from that vocabulary.
Below we can see the addition of the geosparql context in line 4 and the use of the vocabulary, using the defined geosparql: prefix in lines 9, 11 and 15.
If we wanted to use other vocabularies like DCAT or FOAF, we would add them to the context with a
prefix and then the vocabulary namespace.  We could then use terms from that vocabulary in our document
following the same prefix:term pattern.
 1{
 2    "@context": {
 3      "@vocab": "https://schema.org/",
3      "@vocab": "https://schema.org/",
 4      "geosparql": "http://www.opengis.net/ont/geosparql#"
 5    },
 6    "@id": "https://example.org/id/XYZ",
 7    "@type": "Dataset",
 8    "name": "Data set name",
 9    "geosparql:hasGeometry": {
10        "@type": "http://www.opengis.net/ont/sf#Point",
11        "geosparql:asWKT": {
12            "@type": "http://www.opengis.net/ont/geosparql#wktLiteral",
13            "@value": "POINT(-76 -18)"
14        },
15        "geosparql:crs": {
16            "@id": "http://www.opengis.net/def/crs/OGC/1.3/CRS84"
17        }
18    }
19}
20  
Graph#
The next section we will discuss is the graph part of the document seen in lines 5-9 below.  This is where the properties and
values of our resource are described.
 1{
 2    "@context": {
 3        "@vocab": "https://schema.org/"
 4    },
3        "@vocab": "https://schema.org/"
 4    },
 5    "@type": "CreativeWork",
 6    "@id": "https://example.org/id/XYZ",
 7    "name": "Name or title of the document",
 8    "description": "Description of the creative work to aid in searching",
 9    "url":  "https://www.sample-data-repository.org/creativework/report.pdf"
10}
First though, let’s visit a couple special properties in our
document.
Node identifiers (@id)#
 1{
 2    "@context": {
 3        "@vocab": "https://schema.org/"
 4    },
 5    "@type": "CreativeWork",
 6    "@id": "https://example.org/id/XYZ",
 7    "name": "Name or title of the document",
 8    "description": "Description of the creative work to aid in searching",
 9    "url":  "https://www.sample-data-repository.org/creativework/report.pdf"
10}
The first special property is the @id property.  This is the identifier for the top level node in the
graph and is typically the identifier for the record.
Note
graph and is typically the identifier for the record.
Note
It should be noted this is the not the ID for the object being described but rather the record itself.
If you are describing a dataset with a DOI, for example, the @id is not that DOI.  Rather it is the
ID, potentially the URL, for the metadata record about that dataset.  Your dataset ID would be included
in the metadata record using the the identifier property.
It’s good practice to ensure all your records have an @id property.  If there is no value then the
resource is identified by what is known as a blank node.  Such identifiers do not allowing use in
a Linked Open Data approach and are generally not recommended.
The @id should be the URL for the metadata record itself.  Not the HTML page the record is in.  However,
these might be the same if use use content negotiation to select between HTML and JSON-LD representations
of the record.
Type identifiers (@type)#
 1{
 2    "@context": {
 3        "@vocab": "https://schema.org/"
 4    },
 5    "@type": "CreativeWork",
 6    "@id": "https://example.org/id/XYZ",
 7    "name": "Name or title of the document",
 8    "description": "Description of the creative work to aid in searching",
8    "description": "Description of the creative work to aid in searching",
 9    "url":  "https://www.sample-data-repository.org/creativework/report.pdf"
10}
The next property to focus on is the @type property.  This describes the type of record we are describing.
Note
In Schema.org and in most vocabularies, types will be named with a capitol letter.  Properties on these
types will be all lower case.  So, CreateWork, as a type, starts with a upper case C.  Then, name, as
a property on the CreateWork type, starts with a lower case n.
For OIH these type for the various thematic profiles are defined in the documentation for the types.
Other properties#
At this point we can return to look at the other properties for our type.
 1{
 2    "@context": {
 3        "@vocab": "https://schema.org/"
 4    },
 5    "@type": "CreativeWork",
 6    "@id": "https://example.org/id/XYZ",
 7    "name": "Name or title of the document",
 8    "description": "Description of the creative work to aid in searching",
 9    "url":  "https://www.sample-data-repository.org/creativework/report.pdf"
10}
As noted, we are using Schema.org type for OIH.  In this case, as mentioned,
this is type  CreativeWork.  So any of the properties
seen at the Schema.org site can be used.   The key properties of value to the OIH implementation can then
be found, for this type, in the Documents thematic type.
For the OIH implementation, we will use the following properties as core properties we
want all OIH documents to have.  These include:
name:  The name of the document or item being described
description:  A description of the document or item being described
url: A URL for the document or item being described.
Domain and range#
The domain of a property identifies the type of object it can be applied to.
So if the domain of a property like schema.org/knowsAbout
is Person and Organization.  Then that property can only be used on those types.
For example, it would not be correct to use knowsAbout on a resource of type Dataset.
The range of a property identifies the type of object the property can point to.  In
the case of knowAbout, we see its range as Text, Thing or URL.  This means the property
can point to a Text, Thing or URL object.
In schema.org, the domain will be identified as “Used on these types”, and the
In schema.org, the domain will be identified as “Used on these types”, and the
range will be identified as “Values expected to be one of these types”.  You can see
this at the schema.org/knowsAbout page.
Thing and DataType#
The Thing and Datatype types
are two special types we should mention.  Thing is the upper level and most generic
type in schema.org.   Everything in schema.org is descended from Thing.  So when
knowsAbout says its range includes Thing, it means you can use any type in schema.org
as the value of that property.
DataType is the basic data type Thing in schema.org and is a subclass of rdfs:Class.
A DataType includes things like Integers, Strings, DateTime, etc.  So, using again
knowsAbout, we see the range includes not only Thing by also the DataTypes Text
and URL, where URL is actually a sub-type of Text.
Thematic Patterns#
Introduction#
These thematic patterns are managed by OIH and the community to add in the discovery and use
of ocean related resources.  The patterns are simple examples of Schema.org types, with a focus
on the properties and type relations of value to the Ocean InfoHub and the community it engages.
These “profiles” provide both a starting point for new users and a catalysis for discussion and
extension with the community.
Thematic Profiles#
These profiles represent a reference implementation of schema.org Types
related to the identified ODIS thematic areas.  They provide a set of minimal elements
and notes on more detailed elements.
These are not final and will evolve with community input.  As this process moves forward we will implement
versioning of the profiles to provide stable implementations providers can reliably leverage in their workflows.
Core Profiles#
Six key categories of interest:
Experts and Institutions
Documents
Spatial Maps
Projects
Training
Vessels
Supporting Profiles#
In support of these five thematic types above, these cross cutting types and properties were
selected for attention.  They represent some key patterns people may wish to leverage when
describing their resources.
Spatial Geometry
Services
Term Lists
Languages
Linking to Principles
Identifier Patterns
See also
For OIH the focus is on generic documents which can scope reports, data and other resources.
For OIH the focus is on generic documents which can scope reports, data and other resources.
In those cases where the resources being described are of type Dataset you may wish to review
patterns developed for GeoScience Datasets by the ESIP
Science on Schema community.
Training#
About#
A thematic type to describe potential training activities.  In Schema.org a Course
is a subtype of CreativeWork and LearningResource.
As defined from https://schema.org/Course:
Course: A description of an educational course which may be offered as distinct
instances at which take place at different times or take place at different
locations, or be offered through different media or modes of study. An
educational course is a sequence of one or more educational events and/or
creative works which aims to build knowledge, competence or ability of learners.
We can start by looking at a basic Course description.
Simple Course#
A basic course might simply present the name and description of the course along
with a few other key properties.
 1{
 2    "@context": {
 3        "@vocab": "https://schema.org/"
 4    },
 5    "@id": "https://example.org/id/course/2",
 6    "@type": "Course",
 7    "courseCode": "SD100",
 8    "name": "Structured Data",
 9    "description": "An introduction to authoring JSON-LD documents for OIH",
10    "provider": {
11        "@type": "Organization",
12        "name": "Example University",
11        "@type": "Organization",
12        "name": "Example University",
13        "@id": "https://grid.ac/institutes/grid.475727.4",
14        "description": "UN Department of Economic and Social Affairs Sustainable Development"
15    }
16}
import json
from pyld import jsonld
import os, sys
currentdir = os.path.dirname(os.path.abspath(''))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0, parentdir)
from lib import jbutils
with open("../../../odis-in/dataGraphs/thematics/training/graphs/course2.json") as dgraph:
    doc = json.load(dgraph)
context = {
    "@vocab": "https://schema.org/",
}
compacted = jsonld.compact(doc, context)
jbutils.show_graph(compacted)
Here we can see the emphasized line 7 and lines 10-15 highlighting some
unique types.
courseCode:
The courseCode is used to provide the ID used by the provider for this course.
provider:
The provider is the organization offering the course.
This property is from the CreativeWork supertype.  In this case the provider may
be of type Organization or Person.  For Ocean InfoHub these would be described in
the Experts and Institutions section.
Note
In this case you can see we use a simple @id in the provider property.  You can
see this same @id used in the  Experts and Institutions section.
By doing this, we connect this provider to the Organization described by that document.
As such these will be connected in the graph.  So there is no need to duplicate
the information here.  This is a common graph pattern that allows us to simply
connect resources.   If there was no existing Organization or Person resource you could
simply create one here.   However, you may also find it useful to create a given
resource and link to it in the graph.
Detailed Course#
There are a wide range of properties that can be used to describe a course.
Many of these can be seen at the Course type as
the properties from Course and properties
from LearningResource.
the properties from Course and properties
from LearningResource.
We wont go into the details of each property here, but we will show a couple.
The example below present two.
 1{
 2    "@context": {
 3        "@vocab": "https://schema.org/",
 4        "endDate": {
 5            "@type": "http://www.w3.org/2001/XMLSchema#dateTime"
 6        },
 7        "startDate": {
 8            "@type": "http://www.w3.org/2001/XMLSchema#dateTime"
 9        }
10    },
11    "@id": "https://example.org/id/course/2",
12    "@type": "Course",
13    "courseCode": "SD100",
14    "name": "Structured Data",
15    "description": "An introduction to authoring JSON-LD documents for OIH",
16    "teaches": "JSON-LD",
17    "provider": {
18        "@type": "Organization",
19        "name": "Example University",
20        "@id": "https://grid.ac/institutes/grid.475727.4",
21        "description": "UN Department of Economic and Social Affairs Sustainable Development"
22    },
23    "hasCourseInstance": [
24        {
22    },
23    "hasCourseInstance": [
24        {
25            "@type": "CourseInstance",
26            "courseMode": [
27                "MOOC1",
28                "online"
29            ],
30            "endDate": "2019-03-21",
31            "startDate": "2019-02-15",
32            "attendee": {
33                "@type": "Person",
34                "name": "Jane Doe",
35                "jobTitle": "Professor",
36                "telephone": "(425) 123-4567",
37                "url": "http://www.janedoe.com",
38                "identifier": {
39                    "@id": "ID_value_string",
40                    "@type": "PropertyValue",
41                    "propertyID": "This can be text or URL for an ID like ORCID",
42                    "url": "https://foo.org/linkToPropertyIDPage",
43                    "description": "Optional description of the ID"
44                }
45            }
46        },
47        {
48            "@type": "CourseInstance",
49            "courseMode": [
50                "MOOC2",
51                "online"
52            ],
53            "endDate": "2019-05-21",
52            ],
53            "endDate": "2019-05-21",
54            "startDate": "2019-04-15"
55        }
56    ]
57}
import json
from pyld import jsonld
import os, sys
currentdir = os.path.dirname(os.path.abspath(''))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0, parentdir)
from lib import jbutils
with open("../../../odis-in/dataGraphs/thematics/training/graphs/course1.json") as dgraph:
    doc = json.load(dgraph)
context = {
    "@vocab": "https://schema.org/",
}
compacted = jsonld.compact(doc, context)
jbutils.show_graph(compacted)
Line 16 shows the teaches property.  It
should be noted while this propery can point to simple text, it is
should be noted while this propery can point to simple text, it is
also possible to leverage DefinedTerm.  This
means a controlled vocabulary can be used to describe what the course
teaches.  Ocean InfoHub provides some more information and links to further
information on defined term in
the Keywords and Defined Terms section.
Lines 23-56 show using a hasCourseInstance
property to show instances where this course is being taught.  Also of note
in this example are the lines 4-9 in the context where we can type the
endDate and startDate as type dateTime.  By doing this we must provide the
dates in a format that is in line with the [XML Datatype] and in particular the
ISO 8601 Data and Time Formats.
By doing this we can then later conduct searches on the graph that use date ranges
to allow us to find courses, or any resources, that are being taught in a
given time period.
References#
RDA Education and Training on handling of research data IG
DC Tabular Application Profiles (DC TAP) - Primer
https://www.w3.org/TR/xmlschema11-2/
Use YYYY-MM-DDThh:mm:ss or YYYY-MM-DD
http://www.marinetraining.eu/
Example page
https://oceanexpert.org/
Example page
OCTO
https://oceansummerschools.iode.org/
Example page
OCTO
https://oceansummerschools.iode.org/
https://octogroup.org/webinars/
https://catalogue.odis.org/search/type=16
https://clmeplus.org/
Languages#
About#
JSON-LD fully support the identification of the language types.  For the canonical
guide refernece JSON-LD 1.1 Language-indexing section.
Properties such as label, description, keyword and others can be
extended in the context with a container language attribute notation.
For example:
{
  "@context": "https://schema.org/",
  "@type": "Person",
  "name": {"@value": "Jane Doe","@language": "en"},
  "jobTitle": "Professor",
  "telephone": "(425) 123-4567",
  "url": "http://www.janedoe.com"
}
Shows the name Jane Doe as typed english.
Use standard language codes (fr, es, en, de, etc) to
be used when describing these properties.   A list of codes can be seen
at the [Online Browsing Platform (OBP)](https://www.iso.org/obp/ui/#search and)
and Popular standards ISO 3166 Country Codes.
Additional use the 2-letter codes is demonstrated below.
 1{
 2    "@context": {
 3      "vocab": "http://example.com/vocab/",
 4      "label": {
 5        "@id": "vocab:label",
 6        "@container": "@language"
6        "@container": "@language"
 7      }
 8    },
 9    "@id": "http://example.com/queen",
10    "label": {
11      "en": "The Queen",
12      "de": [ "Die Königin", "Ihre Majestät" ]
13    }
14  }
import json
from pyld import jsonld
import os, sys
currentdir = os.path.dirname(os.path.abspath(''))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0, parentdir)
from lib import jbutils
with open("../../../odis-in/dataGraphs/thematics/languages/graphs/language.json") as dgraph:
    doc = json.load(dgraph)
context = {
    "@vocab": "https://schema.org/",
}
compacted = jsonld.compact(doc, context)
jbutils.show_graph(compacted)
In graph space the resulting triples from the above are:
<http://example.com/queen> <http://example.com/vocab/label> "Die Königin"@de .
<http://example.com/queen> <http://example.com/vocab/label> "Ihre Majestät"@de .
<http://example.com/queen> <http://example.com/vocab/label> "The Queen"@en .
with language encoding attributes in place.  These can be used in
searching and result filters.
Note, this can cause issues in query space since the concept of
"Semua orang dilahirkan merdeka dan mempunyai martabat dan hak-hak yang sama. 
Mereka dikaruniai akal dan hati nurani dan hendaknya bergaul satu 
sama lain dalam semangat persaudaraan."
and
"Semua orang dilahirkan merdeka dan mempunyai martabat 
dan hak-hak yang sama. Mereka dikaruniai akal dan hati nurani 
dan hendaknya bergaul satu sama lain dalam semangat persaudaraan."@id
are different and so care must be taken the creation of the SPARQL
queries not to accidentally imposed implicate filters through the use
of language types.
When trying to note the language of a distribution, the approach is a bit different.
Here we are not noting the encoding of the literal value in a record. Rather, we are
providing information about a remote resource.  So for example:
"distribution": [
    {
      "@type": "DataDownload",
      "contentUrl": "https://www.example-data-repository.org/dataset/3300/data/larval-krill.tsv",
      "encodingFormat": "text/tab-separated-values",
      "datePublished": "2010-02-03",
      "inLanguage": "de"	
    }
  ],
The above snippet is using the schema.org/inLanguage property to note the resources is in German.
Multiple distributions with multiple languages would look like
"distribution": [
    {
      "@type": "DataDownload",
      "contentUrl": "https://www.example-data-repository.org/dataset/3300/data/larval-krill_de.tsv",
      "encodingFormat": "text/tab-separated-values",
      "datePublished": "2010-02-03",
      "inLanguage": "de"	
    },
   {
"inLanguage": "de"	
    },
   {
      "@type": "DataDownload",
      "contentUrl": "https://www.example-data-repository.org/dataset/3300/data/larval-krill_en.tsv",
      "encodingFormat": "text/tab-separated-values",
      "datePublished": "2010-02-03",
      "inLanguage": "en"	
    }
  ],
There is also the schema.org/knowsLanguage for use on other types like Person and Organization.
There you could use the short form like:
"knowsLanguage" : "de"
or a more detailed approach like:
"knowsLanguage" : {
      "@type": "Language",
      "name": "Spanish",
      "alternateName": "es"
    }
Licenses#
Schema.org License#
https://schema.org/license
URL
CreativeWork
License as URL - Good#
{
  "@context": "https://schema.org/",
  "license": "https://creativecommons.org/licenses/by/4.0/"
}
License as CreativeWork - Better?#
{
  "@context": "https://schema.org/",
  "license": {
    "@type": "CreativeWork",
    "name": "Creative Commons Attribution 4.0",
    "url": "https://creativecommons.org/licenses/by/4.0/"
  }
}
License as SPDX URL - Best#
Use a simple URL
SPDX creates URLs for many licenses including those that don’t have URLs
From a source that harvesters can rely on (e.g. use URL to lookup more information about the license)
{
  "@context": "https://schema.org/",
  "license": "https://spdx.org/licenses/CC-BY-4.0"
}
OR, include both the SPDX and the Creative Commons URLs in an array:
{
  "@context": "https://schema.org/",
  "license": ["https://spdx.org/licenses/CC-BY-4.0", "https://creativecommons.org/licenses/by/4.0/"]
}