Framing Recommendation claims:
Framing is used to shape the data in a JSON-LD document, using an example frame document which is used to both match the flattened data and show an example of how the resulting data should be shaped.
This sounds to me as if JSON-LD-Parsing + JSON-LD-Framing may be meant to help with mapping back-and-forth between data models carrying semantically equivalent data but having chosen different syntactic models for it. At least this is a common problem I often see in practical data integration and data exchange scenarios. So I tried to test this hypothesis with a pretty simple example of putting the Library input data from the JSON-LD v1.1 Framing Recommendation into a different shape.
I began with this frame:
Frame
{
"@context": {
"@vocab": "http://example.org/"
},
"@type": "Library",
"contains": {}
}
It produces
Framed Output
{
"@context": {
"@vocab": "http://example.org/"
},
"@id": "http://example.org/library",
"@type": "Library",
"contains": {
"@id": "http://example.org/library/the-republic",
"@type": "Book",
"contains": {
"@id": "http://example.org/library/the-republic#introduction",
"@type": "Chapter",
"description": "An introductory chapter on The Republic.",
"title": "The Introduction"
},
"creator": "Plato",
"title": "The Republic"
},
"location": "Athens"
}
Basically the output seems to me like just being a different way to render the tree model in the input @graph
adjacency list. However the purpose was to map the input model onto some slightly different one. So what I looked for was a frame which maps the input model onto a model which chooses to have a books
array and a chapters
array rather than scalar contains
properties:
Desired Framed output
{
"@context": {
"@vocab": "http://example.org/"
},
"@id": "http://example.org/library",
"@type": "Library",
"books": [{
"@id": "http://example.org/library/the-republic",
"@type": "Book",
"chapters": [{
"@id": "http://example.org/library/the-republic#introduction",
"@type": "Chapter",
"description": "An introductory chapter on The Republic.",
"title": "The Introduction"
}],
"creator": "Plato",
"title": "The Republic"
}],
"location": "Athens"
}
However, this is the closest frame I could get to after hours of trial and error:
{
"@context": {
"@vocab": "http://example.org/",
"books": {
"@id": "contains",
"@context": {
"chapters": {
"@id": "contains",
"@container": "@set"
}
}
}
},
"@type": "Library",
"contains": {}
}
It produces a result
{
"@context": {
"@vocab": "http://example.org/"
},
"@id": "http://example.org/library",
"@type": "Library",
"books": {
"@id": "http://example.org/library/the-republic",
"@type": "Book",
"chapters": [{
"@id": "http://example.org/library/the-republic#introduction",
"@type": "Chapter",
"description": "An introductory chapter on The Republic.",
"title": "The Introduction"
}],
"creator": "Plato",
"title": "The Republic"
},
"location": "Athens"
}
which obviously misses the books
array, though. So logically one would conclude: what's left missing is some "@container": "@set"
in the mapping which maps "contains" onto "books". So let's do it:
That Frame should do it:
{
"@context": {
"@vocab": "http://example.org/",
"books": {
"@id": "contains",
"@container": "@set", // <= let's make books an array
"@context": {
"chapters": {
"@id": "contains",
"@container": "@set"
}
}
}
},
"@type": "Library",
"contains": {}
}
Failed: for some reason now the output changes to
{
"@context": {
"@vocab": "http://example.org/"
},
"@id": "http://example.org/library",
"@type": "Library",
"books": [{
"@id": "http://example.org/library/the-republic",
"@type": "Book",
"books": [{
"@id": "http://example.org/library/the-republic#introduction",
"@type": "Chapter",
"description": "An introductory chapter on The Republic.",
"title": "The Introduction"
}],
"creator": "Plato",
"title": "The Republic"
}],
"location": "Athens"
}
wiping out chapters. That's where I gave up. I know this is not a support forum, but after so much time spent on a dozen different frames I am not even sure anymore the recommendation provides any solution to that problem. If so, what's the solution I don't see? Or is this just a nasty bug in json-ld.js used on the JSON-LD playground?
Thanks in advance for any response.