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" }