Skip navigation

The Fresnel Selector Language (FSL) is a language for modeling traversal paths in RDF graphs. It is used as a selector language for the Fresnel display vocabulary for RDF. FSL does not depend on a specific serialization of RDF. It is inspired by the XPath Recommendation and RDFPath language proposals but is not intended to be a full RDFPath language, though it could be extended to become one.

This page provides code snippets demonstrating how to build an FSL path expression using the ANTLR-based FSL parser provided by JFresnel and how to then evaluate this expression on a Jena model or a Sesame repository.

Resources

Java Implementations

Package fr.inria.jfresnel.fsl provides two Java implementations of FSL as well as a standalone FSL parser than can be used by other implementations. The first implementation evaluates FSL path expressions on Jena in-memory RDF models, and requires Jena 2.3 or above. The second implementation is for Sesame 2 RDF repositories and currently works with Sesame 2.0-beta3.

There is also an implentation based on an earlier version of this package that evaluates FSL path expressions on IsaViz in-memory RDF models, and is mainly used to provide Fresnel/FSL developers with a visual debugger for FSL expressions (Figure 1).

FSL Debugger screenshot
Figure 1: Visual FSL Debugger in IsaViz 3.0

Download

Simply download the latest version of JFresnel.

The following sections provide code snippets demonstrating how to evaluate FSL path expressions on Jena models and Sesame repositories.

FSL for Jena

Two main classes are used to evaluate an FSL path on a Jena model:

This first example shows the simplest way of doing so:

import fr.inria.jfresnel.fsl.*; import com.hp.hpl.jena.rdf.model.*; /* Declare the namespace prefix bindings for the prefixes used in the model */ FSLNSResolver nsr = new FSLNSResolver(); // examples of namespace declarations nsr.addPrefixBinding("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"); nsr.addPrefixBinding("rdfs", "http://www.w3.org/2000/01/rdf-schema#"); nsr.addPrefixBinding("foaf", "http://xmlns.com/foaf/0.1/"); /* Declare the RDFS and OWL files that should be loaded for RDFS/OWL awareness */ FSLHierarchyStore fhs = new FSLHierarchyStore(); // see API documentation for details /* Instantiate the evaluator */ FSLJenaEvaluator fje = new FSLJenaEvaluator(nsr, fhs); /* Provide your FSL path expression as a String */ String fslPath = "foaf:Person[foaf:knows/foaf:Person]/foaf:name/text()"; /* File containing the RDF data in RDF/XML */ String rdfFile = "foo/bar.rdf"; /* Evaluate the path on the model and get the results from the evaluation in a Vector */ Vector pathInstances = fje.evaluate(fslPath, FSLPath.NODE_STEP, rdfFile, false);

The result Vector contains as many Vectors as there are path instances in the graph that match the FSL expression. Each one of these Vectors is contains a sequence of alternating nodes and arcs which are respectively instances of com.hp.hpl.jena.rdf.model.Resource or com.hp.hpl.jena.rdf.model.Literal for the nodes, and com.hp.hpl.jena.rdf.model.Statement for the arcs.

The following examples demonstrates how to set the Jena Model directly instead of giving a File path for the RDF model.

import fr.inria.jfresnel.fsl.*; import com.hp.hpl.jena.rdf.model.*; /* Declare the namespace prefix bindings for the prefixes used in the model */ FSLNSResolver nsr = new FSLNSResolver(); // examples of namespace declarations nsr.addPrefixBinding("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"); nsr.addPrefixBinding("rdfs", "http://www.w3.org/2000/01/rdf-schema#"); nsr.addPrefixBinding("foaf", "http://xmlns.com/foaf/0.1/"); /* Declare the RDFS and OWL files that should be loaded for RDFS/OWL awareness */ FSLHierarchyStore fhs = new FSLHierarchyStore(); // see API documentation for details /* Instantiate the evaluator */ FSLJenaEvaluator fje = new FSLJenaEvaluator(nsr, fhs); /* Set the Jena model */ Model jenaModel = ...; fje.setModel(jenaModel); /* Provide your FSL path expression as a String */ String fslPath = "foaf:Person[foaf:knows/foaf:Person]/foaf:name/text()"; /* Build the path (the first step is a node step in this case)*/ FSLPath p = FSLPath.pathFactory(fslPath, nsr, FSLPath.NODE_STEP); /* Evaluate the path on the model and get the results from the evaluation in a Vector */ Vector pathInstances = fje.evaluatePath(p);

FSL for Sesame 2.0

Two main classes are used to evaluate an FSL path on a Sesame repository:

The first example shows how to store RDF from a given URL in a Sesame repository and then evaluate an FSL expression on that repository.

import fr.inria.jfresnel.fsl.*; import org.openrdf.model.*; /* Declare the namespace prefix bindings for the prefixes used in the model */ FSLNSResolver nsr = new FSLNSResolver(); // examples of namespace declarations nsr.addPrefixBinding("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"); nsr.addPrefixBinding("rdfs", "http://www.w3.org/2000/01/rdf-schema#"); nsr.addPrefixBinding("foaf", "http://xmlns.com/foaf/0.1/"); /* Declare the RDFS and OWL files that should be loaded for RDFS/OWL awareness */ FSLHierarchyStore fhs = new FSLHierarchyStore(); // see API documentation for details /* Instantiate the evaluator */ FSLSesameEvaluator fse = new FSLSesameEvaluator(nsr, fhs); /* Provide your FSL path expression as a String */ String fslPath = "foaf:Person[foaf:knows/foaf:Person]/foaf:name/text()"; /* File containing the RDF data in RDF/XML */ String rdfLocation = "http://example.org/bar/foo.rdf"; /* Evaluate the path on the repository and get the results from the evaluation in a Vector */ Vector pathInstances = fse.evaluate(fslPath, FSLPath.NODE_STEP, rdfLocation, false);

The result Vector contains as many Vectors as there are path instances in the graph that match the FSL expression. Each one of these Vectors is contains a sequence of alternating nodes and arcs which are respectively instances of org.openrdf.model.Resource or org.openrdf.model.Literal for the nodes, and org.openrdf.model.Statement for the arcs.

The following examples demonstrates how to set the Sesame repository directly instead of giving a File path or URL for the RDF model.

import fr.inria.jfresnel.fsl.*; import org.openrdf.model.*; import org.openrdf.repository.Repository; /* Declare the namespace prefix bindings for the prefixes used in the model */ FSLNSResolver nsr = new FSLNSResolver(); // examples of namespace declarations nsr.addPrefixBinding("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"); nsr.addPrefixBinding("rdfs", "http://www.w3.org/2000/01/rdf-schema#"); nsr.addPrefixBinding("foaf", "http://xmlns.com/foaf/0.1/"); /* Declare the RDFS and OWL files that should be loaded for RDFS/OWL awareness */ FSLHierarchyStore fhs = new FSLHierarchyStore(); // see API documentation for details /* Instantiate the evaluator */ FSLSesameEvaluator fse = new FSLSesameEvaluator(nsr, fhs); /* Set the Sesame repository */ Repository sesameRepository = ...; fse.setRepository(sesameRepository); /* Provide your FSL path expression as a String */ String fslPath = "foaf:Person[foaf:knows/foaf:Person]/foaf:name/text()"; /* Build the path (the first step is a node step in this case)*/ FSLPath p = FSLPath.pathFactory(fslPath, nsr, FSLPath.NODE_STEP); /* Evaluate the path on the model and get the results from the evaluation in a Vector */ Vector pathInstances = fse.evaluatePath(p);