I want to convert a JSON (not JSON-LD) array to RDF in Java. I have seen similar posts to the forum but not exact answer. The JSON array contains objects and arrays, somethi
You could define a proper @context
and use any JSON-LD converter to create any RDF serialization. Find Java example here and here.
Example
{
"@context":{
"results":{
"@id":"info:stack/49365220/results",
"@container":"@list"
},
"record_id":{
"@id":"info:stack/49365220/record_id"
},
"gender":{
"@id":"info:stack/49365220/gender"
},
"age":{
"@id":"info:stack/49365220/age"
},
"demographics":{
"@id":"info:stack/49365220/demographics"
}
},
"results": [
{
"record_id": "3d87f4df-f17e-4632-9449",
"demographics": { "gender":"female", "race":"", "age":20 }
},
{
"record_id": "ec5ca92d-865a-431f-9984",
"demographics": { "gender":"male", "age":118 }
},
{
"record_id": "0a79ecf0-83d8-4148-9054",
"demographics": { "gender":"female", "age":118 }
},
{
"record_id": "229276f8-1893-480b-b6e7",
"demographics": { "gender":"female", "age":35 }
},
{
"record_id": "0574cc3b-fb9c-495f-851c",
"demographics": { "gender":"female", "age":40 }
},
{
"record_id": "f3ccfdf6-231e-4a3e-bee0",
"demographics": { "gender":"male", "age":118 }
}
]
}
When putting this to Json-Ld Playground (or any other RDF tool) you can produce something like this:
serialized as N-TRIPLE
_:b0 <info:stack/49365220/results> _:b13 .
_:b1 <info:stack/49365220/demographics> _:b2 .
_:b1 <info:stack/49365220/record_id> "3d87f4df-f17e-4632-9449" .
_:b10 <info:stack/49365220/age> "40"^^<http://www.w3.org/2001/XMLSchema#integer> .
_:b10 <info:stack/49365220/gender> "female" .
_:b11 <info:stack/49365220/demographics> _:b12 .
_:b11 <info:stack/49365220/record_id> "f3ccfdf6-231e-4a3e-bee0" .
_:b12 <info:stack/49365220/age> "118"^^<http://www.w3.org/2001/XMLSchema#integer> .
_:b12 <info:stack/49365220/gender> "male" .
_:b13 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> _:b1 .
_:b13 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:b14 .
_:b14 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> _:b3 .
_:b14 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:b15 .
_:b15 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> _:b5 .
_:b15 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:b16 .
_:b16 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> _:b7 .
_:b16 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:b17 .
_:b17 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> _:b9 .
_:b17 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:b18 .
_:b18 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> _:b11 .
_:b18 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> .
_:b2 <info:stack/49365220/age> "20"^^<http://www.w3.org/2001/XMLSchema#integer> .
_:b2 <info:stack/49365220/gender> "female" .
_:b3 <info:stack/49365220/demographics> _:b4 .
_:b3 <info:stack/49365220/record_id> "ec5ca92d-865a-431f-9984" .
_:b4 <info:stack/49365220/age> "118"^^<http://www.w3.org/2001/XMLSchema#integer> .
_:b4 <info:stack/49365220/gender> "male" .
_:b5 <info:stack/49365220/demographics> _:b6 .
_:b5 <info:stack/49365220/record_id> "0a79ecf0-83d8-4148-9054" .
_:b6 <info:stack/49365220/age> "118"^^<http://www.w3.org/2001/XMLSchema#integer> .
_:b6 <info:stack/49365220/gender> "female" .
_:b7 <info:stack/49365220/demographics> _:b8 .
_:b7 <info:stack/49365220/record_id> "229276f8-1893-480b-b6e7" .
_:b8 <info:stack/49365220/age> "35"^^<http://www.w3.org/2001/XMLSchema#integer> .
_:b8 <info:stack/49365220/gender> "female" .
_:b9 <info:stack/49365220/demographics> _:b10 .
_:b9 <info:stack/49365220/record_id> "0574cc3b-fb9c-495f-851c" .
I'd suggest you not hardcoding this conversion.
For RDBMS sources (by the way, why not use them), there is W3C-standardized R2RML (r2rml).
For JSON and XML sources, there is RML, an unofficial extension of R2RML.
RML Mapper is a Java implementation of RML:
$ bin/RML-Mapper -m ~/Desktop/mappings.ttl -o ~/Desktop/results.ttl
In general, you should place rml:iterator "$.results.[*]"
in the rml:logicalSource
section to iterate over array elements. The exact answer depends on which vocabularies you want to use and the data model you want to achieve.
Let's suppose you need something like this:
@prefix exr: <http://example.org/resource/> .
@prefix exo: <http://example.org/ontology/> .
exr:gender_female
a exo:Gender ;
rdfs:label "female" .
exr:gender_male
a exo:Gender ;
rdfs:label "male" .
exr:record_3d87f4df-f17e-4632-9449
a exo:Record ;
exo:patient_age 20 ;
exo:patient_gender exo:gender_female .
exr:record_ec5ca92d-865a-431f-9984
a exo:Record ;
exo:patient_age 118 ;
exo:patient_gender exo:gender_male .
Then your mappings should be:
@prefix rr: <http://www.w3.org/ns/r2rml#>.
@prefix rml: <http://semweb.mmlab.be/ns/rml#>.
@prefix ql: <http://semweb.mmlab.be/ns/ql#>.
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
@prefix exo: <http://example.org/ontology/>.
@prefix exr: <http://example.org/resource/>.
<#RecordMapping>
rml:logicalSource [
rml:source "/home/skralin/Desktop/results.json";
rml:referenceFormulation ql:JSONPath;
rml:iterator "$.results.[*]"
];
rr:subjectMap [
rr:template "http://example.org/resource/record_{record_id}";
rr:class exo:Record
];
rr:predicateObjectMap [
rr:predicate exo:patient_gender;
rr:objectMap [
rr:parentTriplesMap <#GenderMapping>
]
];
rr:predicateObjectMap [
rr:predicate exo:patient_age;
rr:objectMap [
rml:reference "demographics.age" ;
rr:datatype xsd:integer
]
].
<#GenderMapping>
rml:logicalSource [
rml:source "/home/skralin/Desktop/results.json";
rml:referenceFormulation ql:JSONPath;
rml:iterator "$.results.[*].demographics.gender"
];
rr:subjectMap [
rr:template "http://example.org/resource/gender_{$}";
rr:class exo:Gender
];
rr:predicateObjectMap [
rr:predicate rdfs:label;
rr:objectMap [
rml:reference "$"
]
].