json-ld / json-ld.org

JSON for Linked Data's documentation and playground site
https://json-ld.org/
Other
857 stars 152 forks source link

How to describe private default vocabulary in JSON-LD ? #686

Closed st-sunrize closed 4 years ago

st-sunrize commented 5 years ago

I would like to describe metadata by JSON-LD using private default vocabulary, which is not for public but our private or internal use. Referring to W3C recommendation (https://www.w3.org/TR/json-ld/#default-vocabulary), The example of "detailedDescription" and "detailedStyle" which is symbol color of each Article is as follows.

{
  "@context": {
    "@vocab": "https://schema.org/",
    "detailedDescription": null,
    "detailedStyle": null,
    "DetailedStyle": null,
    "primaryLight": null,
    "primaryDark": null
  },
  "@type": "Article",
  ...
  "description": "xxx",
  "detailedDescription": "yyyyyy",
  "detailedStyle": {
    "@type": "DetailedStyle",
    "primaryLight": "#FF3333",
    "primaryDark": "#CC0000"
  }
}

Can I describe "type" vocabulary like "DetailedStyle" ? Is this a right JSON-LD description ?

gkellogg commented 5 years ago

Certainly, just define them using their own IRIs; there's no expectation that their definitions be publicly available, although it is considered a best practice for Linked Data.

To make sure you get the intended meaning of the schema.org context, you might do the following, instead:

{
  "@context": [ "https://schema.org/", {
    "detailedDescription": "http://example.com/my-private-vocabulary#detailedDescription",
    "detailedStyle": "http://example.com/my-private-vocabulary#detailedStyle",
    "DetailedStyle": "http://example.com/my-private-vocabulary#DetailedStyle",
    "primaryLight": "http://example.com/my-private-vocabulary#primaryLight",
    "primaryDark": "http://example.com/my-private-vocabulary#primaryDark"
  }],
  "@type": "Article",
  ...
  "description": "xxx",
  "detailedDescription": "yyyyyy",
  "detailedStyle": {
    "@type": "DetailedStyle",
    "primaryLight": "#FF3333",
    "primaryDark": "#CC0000"
  }
}

Or, you could just define @vocab as ""http://example.com/my-private-vocabulary#" to default other terms to that namespace.

st-sunrize commented 5 years ago

Thank you for the comment. When I use @vocab as the definition of the default vocabulary, I have three plans. Plan A is as follows.

Plan A

{
  "@context": {
    "@vocab": "https://schema.org/",
    "myvoc": "http://example.com/my-private-vocabulary#"
  },
  "@type": "Article",
  ...
  "description": "xxx",
  "myvoc:detailedDescription": "yyyyyy",
  "myvoc:detailedStyle": {
    "@type": "myvoc:DetailedStyle",
    "myvoc:primaryLight": "#FF3333",
    "myvoc:primaryDark": "#CC0000"
  }
}

Plan A is somewhat verbose because there are a lot of 'myvoc:xxx'. To decrease the description "myvoc:xxx", plan B is as follows.

Plan B

{
  "@context": {
    "@vocab": "https://schema.org/",
    "myvoc": "http://example.com/my-private-vocabulary#"
  },
  "@type": "Article",
  ...
  "description": "xxx",
  "myvoc:detailedDescription": "yyyyyy",
  "myvoc:detailedStyle": {
    "@context": {
      "@vocab": "http://example.com/my-private-vocabulary#"
    },
    "@type": "DetailedStyle",
    "primaryLight": "#FF3333",
    "primaryDark": "#CC0000"
  }
}

The second @context could be abbreviated. Plan C is as follows.

Plan C

{
  "@context": {
    "@vocab": "https://schema.org/",
    "myvoc": "http://example.com/my-private-vocabulary#"
  },
  "@type": "Article",
  ...
  "description": "xxx",
  "myvoc:detailedDescription": "yyyyyy",
  "myvoc:detailedStyle": {
    "@type": "DetailedStyle",
    "primaryLight": "#FF3333",
    "primaryDark": "#CC0000"
  }
}

I have no confidence in plan C because the definition of "primaryLight" and "primaryDark" are ambiguous. Do you think which is the better description ?

gkellogg commented 5 years ago

Firstly, rather than using @vocab: http://schema.org/, I would use the following:

{
  "@context": ["http://schema.org/", {
      "myvoc": "http://example.com/my-private-vocabulary#"
  }],
  ...
}

You may be missing some important term definition from schema.org by simply using @vocab.

You could consider using @vocab: http://example.com/my-private-vocabulary# for your own, and then simply detailedDescription, ... within your document, as schema.org will define all its own terms, so you don't need to use embedded contexts, or you could just define all your own terms. you could then have something like the following:

{
  "@context": ["https://schema.org/", {
    "@vocab": "http://example.com/my-private-vocabulary#",
    "detailedStyle": {"@type": "@id"}
  }],
  "@type": "Article",
  "description": "xxx",
  "detailedDescription": "yyyyyy",
  "detailedStyle": {
    "@type": "DetailedStyle",
    "primaryLight": "#FF3333",
    "primaryDark": "#CC0000"
  }
}
st-sunrize commented 5 years ago

Thank you for the comment.

What "detailedStyle": {"@type": "@id"} means ? Is the type of following values @id ?

"detailedStyle": {
    "@type": "DetailedStyle",
    "primaryLight": "#FF3333",
    "primaryDark": "#CC0000"
}
gkellogg commented 5 years ago

@st-sunrize The @type: @id only comes into play when interpreting values of strings. If you had "detailedStyle": "_:b1", then it would interpret "_:b1" as a blank node identifier instead of a string. This becomes apparent when flattening a document:

{
  "@context": [
    "https://schema.org/",
    {
      "@vocab": "http://example.com/my-private-vocabulary#",
      "detailedStyle": {"@type": "@id"}
    }
  ],
  "@graph": [
    {
      "id": "_:b0",
      "type": "Article",
      "description": "xxx",
      "detailedDescription": "yyyyyy",
      "detailedStyle": "_:b1"
    },
    {
      "id": "_:b1",
      "type": "DetailedStyle",
      "primaryLight": "#FF3333",
      "primaryDark": "#CC0000"
    }
  ]
}

Without @type: @id, the value of "detailedStyle" would be {"@id": "_:b1"}.

Setting the type for detailedStyle says nothing about what the expect for "primaryLight" or "primaryDark" which would retain their default meanings as strings.