Closed James-Hudson3010 closed 4 years ago
What you're doing here is trying to shove a Named Graph (i.e. triples with a context URI) into a single graph in rdflib.
If you remove the graph information it works, i.e.:
jsonRepresentation = """
{
"@id": "mne:aaa",
"@type": "rdfs:Class",
"rdfs:comment": "An aaa",
"rdfs:label": "aaa"
}
"""
If you really want the graph with a context, you'll need to do this:
from rdflib import URIRef
g = rdflib.Graph(identifier=URIRef("http://mne.org/#1.0")).parse(data=jsonRepresentation, format='json-ld')
So it's not really an error of rdflib or rdflib-jsonld more a limitation of what you can import.
You would have the same issue trying to import an N-Quads file into an rdflib Graph().
@nicholascar
Note, you can import a json-ld file with one or more named graphs using Dataset
.
Like this:
from rdflib import Dataset
myds = Dataset()
myds.parse(jsonldcontents)
But the test above would still fail because interating a dataset by default iterates the "Default Graph" which in this case is empty. You need to iterate each named context in the Dataset, then iterate triples from each Dataset.
I am not sure I understand. A slightly more complicated jsonRepresentation would look like:
jsonRepresentation = """
{
"@id": "http://mne.org/#1.0",
"@graph": [
{
"@id": "mne:aaa",
"@type": "rdfs:Class",
"rdfs:comment": "An aaa",
"rdfs:label": "aaa"
},
{
"@id": "mne:bbb",
"@type": "rdfs:Class",
"rdfs:comment": "An bbb",
"rdfs:label": "bbb"
}
]
}
"""
Again, this can be processed by https://json-ld.org/playground/ without error, but not rdflib-jsonld.
Why can the playground handle it? Should the playground produce an error?
I believe mne:aaa and mne:bbb must be inside of a "@graph" for it to be valid json-ld.
But, I can confirm that
g = rdflib.Graph( identifier = URIRef( "http://mne.org/#1.0" ) ).parse( data = jsonRepresentation, format = 'json-ld' )
does resolve the problem, but I would have preferred to have the identifier of the graph stored in the json-ld file itself and not outside of it.
I am not sure why I cannot provide an "@id" for the "@graph" in the json-ld. I am sure I am still missing something obvious.
I can also see
https://w3c.github.io/json-ld-syntax/#example-115-identifying-and-making-statements-about-a-graph
which does the same thing I am doing and providing an "@id" for a "@graph".
The playground handles this example without error, but rdflib-jsonld does not appear to parse it correctly.
Try:
g.parse(data=jsonRepresentation, format="json-ld")
g.serialize(format="nquads").decode()
It seems to provide what was asked?
Try:
g.parse(data=jsonRepresentation, format="json-ld") g.serialize(format="nquads").decode()
It seems to provide what was asked?
When I try that I get an error:
Exception: NQuads serialization only makes sense for context-aware stores!
Exception: NQuads serialization only makes sense for context-aware stores!
Yes, back to the first point: rdflib Graph
isn't context aware in that it only knows about &<Subject, Predicate, Object>
(triples), not <Subject, Predicate, Object, Context>
(quads) so shoving <S P O C>
into <S P O>
doesn't work!
If you do want to auto-parse the JSON-LD, as opposed to using custom logic of your own code to loop through individual parts, you are going to have to use an rdflib ConjunctiveGraph
or a Dataset
.
Why can the playground handle it?
Because it's just taking the JSON-LD and expecting to handle quads, not the more limited triples.
I believe mne:aaa and mne:bbb must be inside of a "@graph" for it to be valid json-ld.
In your example they are! You've declared two sets of triples in the single graph. In N-Quads (with some hand-made shorter URLs for readability), this is:
<mne:aaa> <rdf:type> <rdfs:Class> <mne:1.0> .
<mne:aaa> <rdfs:comment> "An aaa" <mne:1.0> .
<mne:aaa> <rdfs:label> "aaa" <mne:1.0> .
<mne:bbb> <rdf:type> <rdfs:Class> <mne:1.0> .
<mne:bbb> <rdfs:comment> "An bbb" <mne:1.0> .
<mne:bbb> <rdfs:label> "bbb" <mne:1.0> .
So two subjects, <mne:aaa>
& <mne:bbb>
, two triples each, single Named Graph (Context) <mne:1.0>
.
Fascinating: Here is my code verbatim. rdflib 4.2.2 -
from rdflib import Dataset
g = Dataset()
jsonRepresentation = """
{
"@id": "http://mne.org/#1.0",
"@graph": [
{
"@id": "mne:aaa",
"@type": "rdfs:Class",
"rdfs:comment": "An aaa",
"rdfs:label": "aaa"
},
{
"@id": "mne:bbb",
"@type": "rdfs:Class",
"rdfs:comment": "An bbb",
"rdfs:label": "bbb"
}
]
}
"""
g.parse(data=jsonRepresentation, format="json-ld")
print(g.serialize(format="nquads").decode())
output:
<mne:bbb> <rdfs:comment> "An bbb" <http://mne.org/#1.0> .
<mne:aaa> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <rdfs:Class> <http://mne.org/#1.0> .
<mne:bbb> <rdfs:label> "bbb" <http://mne.org/#1.0> .
<mne:aaa> <rdfs:comment> "An aaa" <http://mne.org/#1.0> .
<mne:bbb> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <rdfs:Class> <http://mne.org/#1.0> .
<mne:aaa> <rdfs:label> "aaa" <http://mne.org/#1.0> .
This has been cleared up for me.
As this question and answer is probably also useful in a more public forum and not an actual bug, I have created a stackoverflow question. I will answer it in 24 hours when that is allowed, or someone here can with the information provided in this issue.
https://stackoverflow.com/questions/61000017/rdflib-jsonld-parsing-error-with-id-property
I have the following:
Nothing is printed unless I remove "@id": "http://mne.org/#1.0"
Entering this json-ld data into https://json-ld.org/playground/ produces no errors and works as expected.