Gevorg Arutiunian
Gevorg Arutiunian

Reputation: 57

Convert tuples to json using rdf4j

The problem is the following: When parsing a sparql query, I get simplified ast and I need to pass it to a third-party library for further processing, but the functionality out of the box (rdf4j) does not allow transferring ast in a machine-readable format, only tex, I would like to receive in json format.

        StringBuilder qb = new StringBuilder();
        qb.append("    PREFIX has_vaccine_allergen: <http://purl.obolibrary.org/obo/VO_0000531>\n" +
                "    PREFIX chicken_egg_protein_allergen: <http://purl.obolibrary.org/obo/VO_0000912>   \n" +
                "    SELECT distinct ?vaccine_label ?vaccine \n" +
                "    FROM <http://purl.obolibrary.org/obo/merged/VO>\n" +
                "    WHERE {\n" +
                "        ?vaccine rdfs:label ?vaccine_label .\n" +
                "        ?vaccine rdfs:subClassOf ?vaccine_restriction .\n" +
                "        ?vaccine_restriction owl:onProperty has_vaccine_allergen:; owl:someValuesFrom chicken_egg_protein_allergen: .\n" +
                "\t}");
        SPARQLParser parser = new SPARQLParser();

        ParsedTupleQuery q = (ParsedTupleQuery)parser.parseQuery(qb.toString(), null);
        TupleExpr te = q.getTupleExpr();
        System.out.println(te);

Result of code execution:

SelectQuery
[PrefixDecl (prefix=has_vaccine_allergen), PrefixDecl (prefix=chicken_egg_protein_allergen), SelectQuery]
Distinct
   Projection
      ProjectionElemList
         ProjectionElem "vaccine_label"
         ProjectionElem "vaccine"
      Join
         Join
            Join
               StatementPattern
                  Var (name=vaccine)
                  Var (name=_const_9285ccfc_uri, value=http://www.w3.org/2000/01/rdf-schema#label, anonymous)
                  Var (name=vaccine_label)
               StatementPattern
                  Var (name=vaccine)
                  Var (name=_const_4592be07_uri, value=http://www.w3.org/2000/01/rdf-schema#subClassOf, anonymous)
                  Var (name=vaccine_restriction)
            StatementPattern
               Var (name=vaccine_restriction)
               Var (name=_const_a509c4e0_uri, value=http://www.w3.org/2002/07/owl#onProperty, anonymous)
               Var (name=_const_3319983d_uri, value=http://purl.obolibrary.org/obo/VO_0000531, anonymous)
         StatementPattern
            Var (name=vaccine_restriction)
            Var (name=_const_6539d60c_uri, value=http://www.w3.org/2002/07/owl#someValuesFrom, anonymous)
            Var (name=_const_3319a704_uri, value=http://purl.obolibrary.org/obo/VO_0000912, anonymous)

I need get that to json format

Upvotes: 2

Views: 266

Answers (1)

Jeen Broekstra
Jeen Broekstra

Reputation: 22052

First of all: the TupleExpr object (and the tree underneath it) is not the Abstract Syntax Tree (AST), but instead is RDF4J's query algebra model. If you wish to work directly on the AST of a SPARQL query, you can use SyntaxTreeBuilder.parseQuery(queryString) to receive the actual AST. That said, doing query re-processing on either AST or algebra model can work, it depends a bit on what exactly your output is supposed to do which one is the best choice.

For either AST or query algebra model, RDF4J has abstract Visitor implementations that you can freely extend for your own needs. For AST trees, AbstractASTVisitor is a good starting point (make sure you pick the right one, RDF4J has two: one for SeRQL, one for SPARQL). For query algebra models, the place to start is AbstractQueryModelVisitor. There's tons of examples of implementations of either in the RDF4J code base itself. The typical pattern is that you override the meet methods where you want to define your own behavior, taking care to call super.meet() at the end when you're processing a node that is not a leaf.

Upvotes: 1

Related Questions