-
Notifications
You must be signed in to change notification settings - Fork 12
Existing triple and quad representations
This page details different representations for IRIs, literals, triples, quads, and the likes. Its purpose is to understand each proposal and their pros and cons.
Detailed description and links to current implementations on Use cases page
use case | parsers | serializers | other libs | applications |
---|---|---|---|---|
creating quads | ++ | 0 | + | + |
consuming quads | 0 | ++ | + | + |
triple pattern search | 0 | 0 | ++ | + |
RegEx search | 0 | 0 | + | + |
full text search | 0 | 0 | + | + |
graph traversing | 0 | 0 | + | + |
creating quads with a high level API | 0 | 0 | + | ++ |
consuming quads with a high level API | 0 | 0 | + | ++ |
Requirements should be defined based on the evaluated uses cases. Parsers, serializers and other libs will be implemented by advanced users. Therefore the focus of simple APIs should be set on the requirements for applications. The list of requirements should distinguish between features implemented in the core library and interfaces/hooks provided for other libraries.
- low level API
- object/class definitions for nodes, triples, quads
- constructor/factory to create nodes, triples and quads with setters and getters support
- internal representation can be different to the low level API
- Docs: Concepts: http://www.w3.org/TR/rdf11-concepts/
- Standard: http://www.w3.org/TR/rdf-interfaces/
- close mapping of the RDF-Model to class names and methods
- handles prefix mapping
- Environment class can be used to handle different scopes
// create a triple
var triple = rdf.createTriple(
rdf.createNamedNode('http://example.org/cartoons#Tom'),
rdf.createNamedNode('http://xmlns.com/foaf/0.1/givenName'),
rdf.createLiteral('Tom', 'en')
);
var graph = rdf.createGraph();
graph.add(triple);
var store = rdf.createStore();
store.add('http://example.org/cartoons#TomAndJerry', graph);
Representation used internal by the reference implementation without methods:
var triple = {
subject: {
interfaceName: 'NamedNode'
nominalValue: 'http://example.org/cartoons#Tom'
},
predicate: {
interfaceName: 'NamedNode'
nominalValue: 'http://xmlns.com/foaf/0.1/givenName'
},
object: {
interfaceName: 'Literal'
nominalValue: 'Tom'
language: 'en'
datatype: null
}
};
- Triple SPO properties are:
.subject
,.predicate
,.object
- Node type property is:
.interfaceName
[NamedNode|BlankNode|Literal] - values are accessible via:
.toString
,.valueOf
,.toNT
, see the spec for further details - quads are implemented as RDF Datasets, called stores in the RDF-Ext spec
- readable class and method names
- Graph/Triple/Node parts are accessible in OO way
-
.equals
method to compare Nodes, Triples and (planed) Graphs - well known JS methods to iterate, filter, test graphs
- heavier than plain JS objects
- requires complex nested function calls to create a triple from scratch
- quads are only implemented as RDF Datasets
- avoid objects for IRIs and literals
- avoid classes/prototypes for triples/quads
- each IRI/literal has exactly one internal representation
var triple = {
subject: 'http://example.org/cartoons#Tom',
predicate: 'http://xmlns.com/foaf/0.1/givenName',
object: '"Tom"@en'
};
var quad = {
subject: 'http://example.org/cartoons#Tom',
predicate: 'http://xmlns.com/foaf/0.1/givenName',
object: '"Tom"@en',
graph: 'http://example.org/cartoons#TomAndJerry'
};
construct | expressed as | JavaScript example |
---|---|---|
IRI | plain JavaScript string | 'http://example.org/cartoons#Tom' |
literal | string surrounded by ""
|
'"Tom"' |
literal with language | string surrounded by "" , and '@' in between |
'"Tom"@en' |
literal with datatype | string surrounded by "" , and ' ^^' in between |
'"1"^^http://www.w3.org/2001/XMLSchema#integer' |
blank node | string starting with _:
|
_:b3 |
triple | plain JavaScript object with subject , predicate , object keys |
(see large example above) |
quad | plain JavaScript object with subject , predicate , object , graph keys |
(see large example above) |
Note in particular that no escaping is applied for literals.
So the English literal a"c
is represented internally as '"a"c"@en'
.
Finding out if something is a literal is done based on the first character of the string.
- Creating IRIs and triples is as easy as creating strings and objects.
- Shallow object hierarchy
- easy to access triple components
- fast creation
- No class/prototype needed for IRIs, literals, triples (so no library needed to make objects)
- IRIs and literals can be compared for equality with
===
- given that they are simple strings, we can thus also compare any IRI/literal with a string
- Literals have a special interpretation of JavaScript's regular strings
- will not look familiar to anybody
- Requires special methods to separate value, datatype, and language of literals
- could be implemented as properties/methods on
String.prototype
though- …but extending native prototypes should probably not be a default
- could be implemented as properties/methods on
TODO: add more pro/cons
source: https://github.com/digitalbazaar/jsonld.js/issues/108#issuecomment-135452746
{
"@default": [{
subject: {type: "IRI", value: "http://example.com/subject"},
predicate: {type: "IRI", value: "http://example.com/predicate"},
object: {type: "IRI", value: "http://example.com/object"}
}, {
subject: {type: "blank node", value: "_:b0"},
predicate: {type: "IRI", value: "http://example.com/predicate"},
object: {type: "literal", value: "foo", datatype: "http://www.w3.org/2001/XMLSchema#string"}
}, {
subject: {type: "IRI", value: "http://example.com/subject"},
predicate: {type: "IRI", value: "http://example.com/predicate"},
object: {type: "literal", value: "English", language: "en"}
}, {
subject: {type: "IRI", value: "http://example.com/subject"},
predicate: {type: "IRI", value: "http://example.com/predicate"},
object: {type: "literal", value: "5", datatype: "http://example.com/number"}
}],
"http://example.com/named-graph": [{ ... }]
}
Statement {
subject: BlankNode,
predicate: NamedNode,
object: Literal,
why: BlankNode
}
{
"subject": {
"id": 0,
"value": "0"
},
"predicate": {
"uri": "http://www.w3.org/2000/01/rdf-schema#label",
"value": "http://www.w3.org/2000/01/rdf-schema#label"
},
"object": {
"value": "This Session",
"datatype": undefined,
"lang": undefined
},
"why": {
"id": 0,
"value": "0"
}
}
From http://www.w3.org/TR/sparql11-results-json/#example :
"results": {
"bindings": [
{
"x" : { "type": "bnode", "value": "r1" },
"hpage": { "type": "uri", "value": "http://work.example.org/alice/" },
"name" : { "type": "literal", "value": "Alice" } ,
"mbox" : { "type": "literal", "value": "" } ,
"blurb": {
"datatype": "http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral",
"type": "literal",
"value": "<p xmlns=\"http://www.w3.org/1999/xhtml\">My name is <b>alice</b></p>"
},
"friend" : { "type": "bnode", "value": "r2" }
},
]} }
property names and values enumerations used in internal representation of triples/quads in rdf-interfaces, jsonld.js, rdflib.js, SPARQL 1.1 Query Results JSON
RDF 1.1 | RDF-interfaces | jsonld.js | rdflib.js | SPARQL 1.1 Query Results JSON |
---|---|---|---|---|
RDF node RDF Term "kinds" [1], "types" [2] [distinct] | interfaceName | type | termType | type |
literal value | nominalValue | value | value/uri/id | value |
language tag | language | language | lang | xml:lang |
datatype IRI(s) | datatype | datatype | datatype | datatype |
RDF 1.1 | RDF-interfaces | jsonld.js | rdflib.js | SPARQL 1.1 Query Results JSON |
---|---|---|---|---|
IRI | NamedNode | IRI | Symbol (symbol) | uri |
Blank node | BlankNode | blank node | BlankNode (bnode) | bnode |
Literal | Literal | literal | Literal (literal) | literal |