Native support for schema:ListItem · Issue #595 · json-ld/json-ld.org · GitHub
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Native support for schema:ListItem #595

Closed
gkellogg opened this issue Feb 21, 2018 · 7 comments
Closed

Native support for schema:ListItem #595

gkellogg opened this issue Feb 21, 2018 · 7 comments
Labels
api defer Issue deferred to future Working Group spec-design syntax

Comments

@gkellogg
Copy link
Member

gkellogg commented Feb 21, 2018

Per a suggestion by @danbri, we may want to add a container type, similar to @list for encoding schema:ItemList serializations, when the values are schema:ListItem and order is set through schema:position. ItemList can be used with text values as well, but this is already reasonably supported natively.

Markup might look like the following:

{
  "@context": {
    "@vocab": "http://schema.org/",
    "itemListElement": {"@container": "@listItem"}
  },
  "@type": "ItemList",
  "@url": "http://en.wikipedia.org/wiki/Billboard_200",
  "name": "Top music artists",
  "description": "The artists with the most cumulative weeks at number one according to Billboard 200",
  "itemListElement": [
    {"@type": "MusicGroup", "name": "Beatles"},
    {"@type": "MusicGroup", "name": "Elvis Presley"},
    {"@type": "MusicGroup", "name": "Michael Jackson"},
    {"@type": "MusicGroup", "name": "Garth Brooks" }
  ]

This would expand to the following:

[
  {
    "@id": "http://en.wikipedia.org/wiki/Billboard_200",
    "@type": ["http://schema.org/ItemList"],
    "http://schema.org/description": [{
      "@value": "The artists with the most cumulative weeks at number one according to Billboard 200"
    }],
    "http://schema.org/itemListElement": [{
      "@type": ["http://schema.org/ListItem"],
      "http://schema.org/item": [{
        "@type": ["http://schema.org/MusicGroup"],
        "http://schema.org/name": [{"@value": "Beatles"}]
      }],
      "http://schema.org/position": [{"@value": 1}]
    },  {
      "@type": ["http://schema.org/ListItem"],
      "http://schema.org/item": [{
        "@type": ["http://schema.org/MusicGroup"],
        "http://schema.org/name": [{"@value": "Elvis Presley"}]
      }],
      "http://schema.org/position": [{"@value": 2}]
    }, {
      "@type": ["http://schema.org/ListItem"],
      "http://schema.org/item": [{
        "@type": ["http://schema.org/MusicGroup"],
        "http://schema.org/name": [{"@value": "Michael Jackson"}]
      }],
      "http://schema.org/position": [{"@value": 3}]
    }, {
      "@type": ["http://schema.org/ListItem"],
      "http://schema.org/item": [{
        "@type": ["http://schema.org/MusicGroup"],
        "http://schema.org/name": [{"@value": "Garth Brooks"}]
      }],
      "http://schema.org/position": [{"@value": 3}]
    }
  ],
  "http://schema.org/name": [{"@value": "Top music artists"}]
}]

Otherwise, it works like @list.

When compacting, the processor will re-order items based on position, and ignore any nextItem or previousItem entries.

Expansion shows 1-base position, but could be 0-base as well. Note that specific position values are lost when compacting, and duplicate values may lead to undefined relative ordering.

@gkellogg gkellogg added this to the JSON-LD 1.1 milestone Feb 21, 2018
@workergnome
Copy link

Is there any reason to explicitly add that functionality for Schema itemLists, as opposed to, say, ORE Aggregations with ordered proxies or ActivityStream OrderedCollections?

We've got lots of different patterns for ordering RDF sets across many ontologies, and I worry that blessing more than one (which we have with rdf:List) means that we'd need a good reason not to bless them all.

@gkellogg
Copy link
Member Author

Aside from the politics of gaining support for a WG, most current use of JSON-LD on the web is for schema.org.

There are certainly other useful ontologies, and if someone shows up with a compelling use case and evidence of the impact it would make, we would likely consider.

However, this is a valid concern.

@dlongley
Copy link
Member

Seems like you could do something more general like:

"itemListElement": {
  "@container": {
    "@type": "@itemList",
    "@itemType": "http://schema.org/ListItem",
    "@itemProperty": "http://schema.org/itemListElement"
    "@itemPosition": "http://schema.org/position"
  }
}

Provided that there's a common pattern for these types of "item list" containers.

@gkellogg
Copy link
Member Author

@dlongley is on to something, although more generic keywords might be useful, basically support common patterns in indirect containers, such as listItem, Ordered Link Ontology, and others.

Examining Turtle representations of these lists:

schema:ItemList

@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix schema: <http://schema.org/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

<https://example.com/dresses> schema:name "Dresses" .

<https://example.com/dresses/real> schema:name "Real Dresses" .

 [
     a schema:BreadcrumbList;
     schema:itemListElement [
       a schema:ListItem;
       schema:item <https://example.com/dresses>;
       schema:position 1
     ],  [
       a schema:ListItem;
       schema:item <https://example.com/dresses/real>;
       schema:position 2
     ]
 ] .

This uses an indirection to a ListItem referenced from an itemListElement, referencing the ordered resource using item. Ordering is indicated by position. itemListElement is a property of ItemList, or a derivative class. The size of the list may be indicated using numberOfItems, and individual ListItems may be linked together using nextItem and previousItem.

Interestingly, each ListItem caries out a similar purpose as schema:Role, and in a parallel universe, a ListItem might have been a kind of Role, and linkage would be performed based on parallel incoming and outgoing properties.

Ordered List Ontology

@prefix xsd:     <http://www.w3.org/2001/XMLSchema#> .
@prefix dc:      <http://purl.org/dc/elements/1.1/> .
@prefix olo:     <http://purl.org/ontology/olo/core#> .
@prefix mo:      <http://purl.org/ontology/mo/> .
@prefix ex:      <http://example.org/> .
 
ex:FunkyPlaylist a olo:OrderedList ;
   dc:title "Funky Playlist" ;
   dc:description "A playlist full of funky legends" ;
   dc:creator <http://foaf.me/zazi#me> ;
      olo:length 2 ;
      olo:slot [   
         olo:index 1 ;
         olo:item ex:SexMachine
      ] ;
      olo:slot [
         olo:index 2 ;
         olo:item ex:GoodFoot
      ] .
 
ex:SexMachine a mo:Track ;
   dc:title "Sex Machine" ;
   dc:creator <http://dbpedia.org/resource/James_Brown> .
 
ex:GoodFoot a mo:Track ;
   dc:title "Good Foot" .

This uses an indirection to a Slot referenced from an slot , referencing the ordered resource using item. Ordering is indicated by index. slot is a property of OrderedList, or a derivative class. The size of the list may be indicated using length, and individual ListItems may be linked together using next and previous.

ORE Specification

ORE defines a Proxy type, which can serve as an intermediary between resources. While it doesn't define an ordering directly, a hypothetical xyzzy:hasNext predicate could be used to link Proxy resources to each other.

@prefix ore: <http://www.openarchives.org/ore/terms/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xyz: <http://example/xyz/> .

<ReM-1> a ore:ResourceMap ;
  ore:describes <A-1> .

<A-1> a ore:Aggregation ;
  ore:isDescribedBy <ReM-1> ;
  ore:aggregates <AR-1>, <AR-2> .

<P-1> a ore:Proxy ;
  ore:proxyFor <AR-1> ;
  ore:proxyIn <A-1> ;
  xyz:hasNext <P-2> .

<P-2> a ore:Proxy ;
  ore:proxyFor <AR-2> ;
  ore:proxyIn <A-1> .

<AR-1> a rdf:Resource .
<AR-2> a rdf:Resource .

Note that the proxies have an inverse relationship to their aggregation, and that the Aggregation is an additional intermediate object from the ResourceMap.

Ordering between proxies is not directly defined, and this describes a form of reification similar to schema:Role. Analogies with OLO and ItemList are quite different, and this is likely not suitable for JSON-LD syntactic sugar.

ActivityStream Ordered Collections

The Ordered Collection is done using existing JSON-LD @list support using an orderedItem term having @container: @list. The following JSON-LD example is rendered in Turtle to illustrate:

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "summary": "Object history",
  "type": "OrderedCollection",
  "totalItems": 2,
  "orderedItems": [
    {
      "type": "Create",
      "actor": "http://www.test.example/sally",
      "object": "http://example.org/foo"
    },
    {
      "type": "Like",
      "actor": "http://www.test.example/joe",
      "object": "http://example.org/foo"
    }
  ]
}
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix as: <https://www.w3.org/ns/activitystreams#> .

 [
     a as:OrderedCollection;
     as:items ([
         a as:Create;
         as:actor <http://www.test.example/sally>;
         as:object <http://example.org/foo>
       ] [
         a as:Like;
         as:actor <http://www.test.example/joe>;
         as:object <http://example.org/foo>
       ]);
     as:summary "Object history";
     as:totalItems "2"^^xsd:nonNegativeInteger
 ] .

Consequently, the ActivityStreams Ordered Collection doesn't introduce any new intervening resources.

Conclusions

Both ItemList and OLO use similar paradigms with intermediaries used to describe ordered relationships, however given common authorship (@danbri), that's not too unusual. But, this does offer a generalizable mechanism for describing such relationships, without binding directly to any particular vocabulary. @dlongley's example might be re-stated with more generic keywords:

"itemListElement": {
  "@container": {
    "@type": "http://schema.org/ListItem",
    "@item": "http://schema.org/item"
    "@position": "http://schema.org/position",
    "@next": "http://schema.org/nextItem",
    "@previous": "http://schema.org/previousItem"
  }
}

In this case, the fact that @container is an object signals that such an indirect mechanism is to be used, and the keyword attributes describe the properties of the intermediate resource used to connect. It does not describe properties of the containing resource, such as numberOfItems.

@danbri
Copy link

danbri commented Feb 24, 2018

(fwiw I didn't work on OLO)

Baking in just schema.org feels a bit off. But it is certainly true that JSON-LD's use of JSON arrays for property repetition confuses audiences who don't simultaneously understand JSON's initial flaws regarding field repetition and also RDF's need for explicit order.

@gkellogg gkellogg added defer Issue deferred to future Working Group and removed under-review labels Apr 9, 2018
@gkellogg gkellogg removed this from the JSON-LD 1.1 milestone Apr 9, 2018
@gkellogg
Copy link
Member Author

gkellogg commented Apr 9, 2018

Deferred to WG due to https://json-ld.org/minutes/2018-04-10/#resolution-3.

@gkellogg
Copy link
Member Author

Closed in favor of w3c/json-ld-syntax#15.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api defer Issue deferred to future Working Group spec-design syntax
Projects
None yet
Development

No branches or pull requests

4 participants