GenJ is a ShEx extension to leverage ShEx's unambiguous, ordered traversal of RDF graphs to produce JSON documents.
from the ShEx Demo (look for [Popup] or link in validation messages):
#BASE <http://base.example/#>
PREFIX ex: <http://ex.example/#>
PREFIX foaf: <http://xmlns.com/foaf/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX GenJ: <http://shexspec.github.io/extensions/GenJ/>
%GenJ:{ @id %}
start = <IssueShape>
<IssueShape> {
ex:state (ex:unassigned ex:assigned) %GenJ:{ state %},
ex:reportedBy @<User> %GenJ:{ rprtBy @id %},
ex:reportedOn xsd:dateTime %GenJ:{ rprtOn %},
(ex:reproducedBy @<User> %GenJ:{ rpdcBy @id %},
ex:reproducedOn xsd:dateTime %GenJ:{ rpdcOn %}
)?,
ex:related @<IssueShape>*
}
<User> {
(foaf:name xsd:string %GenJ:{ name %}
| foaf:givenName xsd:string+ %GenJ:{ fname %},
foaf:familyName xsd:string %GenJ:{ lname %}
),
foaf:mbox IRI %GenJ:{ email %},
foaf:phone IRI? %GenJ:{ tel %}
}
#BASE <http://base.example/#>
PREFIX ex: <http://ex.example/#>
PREFIX foaf: <http://xmlns.com/foaf/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
<Issue1>
ex:state ex:unassigned ;
ex:reportedBy <User2> ;
ex:reportedOn "2013-01-23T10:18:00"^^xsd:dateTime ;
ex:reproducedBy <Thompson.J> ;
ex:reproducedOn "2013-01-23T11:00:00"^^xsd:dateTime ;
# ex:related <Issue2>, <Issue3>
.
<User2>
foaf:givenName "Bob" ;
foaf:familyName "Smith" ;
foaf:mbox <mailto:bob@example.org>
.
<Thompson.J>
foaf:givenName "Joe", "Joseph" ;
foaf:familyName "Thompson" ;
foaf:phone <tel:+456> ;
foaf:mbox <mailto:joe@example.org>
.
{
"@context": {
"ns0": "http://ex.example/#",
"state": "ns0:state",
"rprtBy": "ns0:reportedBy",
"ns1": "http://xmlns.com/foaf/",
"fname": "ns1:givenName",
"lname": "ns1:familyName",
"email": "ns1:mbox",
"ns2": "http://www.w3.org/2001/XMLSchema#",
"rprtOn": {
"@id": "ns0:reportedOn",
"@type": "ns2:dateTime"
},
"rpdcBy": "ns0:reproducedBy",
"tel": "ns1:phone",
"rpdcOn": {
"@id": "ns0:reproducedOn",
"@type": "ns2:dateTime"
}
},
"@id": "Issue1",
"state": "http://ex.example/#unassigned",
"rprtBy": {
"@id": "User2",
"fname": "Bob",
"lname": "Smith",
"email": "mailto:bob@example.org"
},
"rprtOn": "2013-01-23T10:18:00",
"rpdcBy": {
"@id": "Thompson.J",
"fname": [
"Joe",
"Joseph"
],
"lname": "Thompson",
"email": "mailto:joe@example.org",
"tel": "tel:+456"
},
"rpdcOn": "2013-01-23T11:00:00"
}