User Guide

Welcome to the Turtle Editor Viewer. It's a place to write or load RDF, see it drawn as a diagram, and ask it questions with SPARQL. Everything runs in your browser, so nothing you paste in leaves your machine. It understands RDF 1.2 and SPARQL 1.2, with a few gaps listed in section 6, and it can check your data against SHACL shapes (section 5). This guide walks through what's on the screen and what each part does.

Where your data goes: nowhere. Parsing, drawing, querying, reasoning and validation all run inside the page. The only times the browser talks to another server are the ones you ask for: a URL you load, or a SERVICE clause in a query you run. Section 8 spells this out, including what the browser itself enforces.

1. Getting Started

What you're looking at

The window is split into two panes, and you can drag the bar between them to change their widths:

The editor pane has a row of tabs along the top: the document you start with, plus any query results or extra files you open. More on that in a moment.

2. Working with Data (Editor Pane)

Getting data in

Three ways, take your pick:

  1. Type or paste straight into the editor.
  2. Open File in the toolbar opens a file from your computer. Turtle (.ttl), RDF/XML (.rdf, .xml), JSON-LD (.json, .jsonld) and Graphviz DOT (.dot) all work, and the tab takes the file's name.
  3. Load URL in the Graph toolbar (right pane) fetches a file from the web. The server hosting it has to allow cross-origin requests (CORS), which most public data servers and GitHub raw links do.

You can also put the URL straight into the page address so a link opens ready-loaded; see URL parameters at the end.

The editor works out the format from the content as you type, so you don't usually need to tell it. If it guesses wrong, the Language dropdown sets it by hand.

A document that uses relative IRIs (<hasChild> rather than <http://example.org/hasChild>, or a relative @id in JSON-LD) has them resolved against http://example.org/, in every syntax. An editor pane has no address of its own to offer, and the query and validation engines reject an entire graph that contains an IRI with no scheme, so resolving them keeps one such term from costing every query over the document.

Tabs

The editor can hold several documents at once, each in its own tab:

Each tab remembers its own text, its own language and its own choice of subjects for the diagram, so flicking between tabs brings each diagram straight back. Close a tab with its ×; you can close any tab, including Source, except the last one standing. Closing a tab never touches what's in the others.

Two things to keep in mind:

Editor settings

The toolbar above the editor has:

Saving

Save File downloads the current tab's text (as turtle-file.ttl, so rename it once it lands).

3. Visualizing Graphs

The diagram is drawn with Graphviz from the subjects you pick.

Choosing what to draw

  1. As you type, the app reads your data and lists every subject it finds (anything that has properties) in the box on the right of the editor toolbar.
  2. Click subjects in that list to draw them; Ctrl-click or Shift-click to pick several. The diagram follows the selection.
  3. Type in the Filter subjects box to narrow the list. It matches on the label as well as the IRI, so either will find it.
  4. Get All in the Graph toolbar draws the first ten subjects. When you load a new file the first ten are picked for you as well, so there's something to look at straight away.

Show labels, next to the filter box, swaps IRIs for names. If a subject has an rdfs:label or skos:prefLabel, the list shows that instead of ex:shop-0042. Where two subjects share a name the IRI is added after it so you can still tell them apart, and hovering over any entry shows its full IRI. It's on when the page opens; untick it to list IRIs.

Blank nodes show up too, when they're the top of a structure rather than nested inside another subject. Ones with a label in the file (_:g_00) are listed under that label; anonymous ones ([] a owl:AllDisjointClasses) are numbered anon-0, anon-1… in the order they appear. Those names stay put while you edit, so a blank node you've picked stays drawn.

Options

The Graph toolbar lets you change how the diagram is laid out and drawn:

RDF 1.2: triple terms and annotations

RDF 1.2 lets a triple be talked about. In Turtle that looks like <<( :shop :founded "1921" )>> when you refer to the triple directly, or :shop :founded "1921" {| :claimedBy :source |} when you attach notes to it as you write it. Under the hood both use rdf:reifies and a triple term.

The diagram draws each triple term as its own node, in dark green, showing the triple it stands for. Blank nodes look just as they always have.

Tick Link Triple Terms and each green node also gets dashed dark-green arrows to the subject and the object it mentions, labelled subject and object, wherever those happen to be in the diagram. They don't affect the layout, so switching them on won't rearrange anything.

Getting around

Exploring outwards

Click any node in the diagram and a panel opens listing everything in the data that refers to it — every subject of a triple whose object is the thing you clicked. It works for an IRI, a literal and a blank node alike, since all three are nodes you can click.

Each entry has a checkbox, ticked when that subject is already drawn:

So you can start from a single subject and walk the graph outwards by following what points at what, which is usually easier than hunting for the right name in the subject list — especially when the IRIs are opaque. The names in the panel are the same ones the subject list shows, labels and all, and hovering over an entry gives its full IRI.

The panel sits over the top-right of the diagram and stays until you close it with its ×, so you can tick several things in turn and watch the picture grow. Ticking here is the same act as selecting in the subject list: the two always agree, and whichever tab you are on keeps its own selection.

4. Querying with SPARQL

The SPARQL & SHACL panel at the bottom right runs SPARQL against the tab that's in front. (Its other job, validation, is section 5.)

Running a query

  1. Write your query in the box. It has syntax colouring, and the tab-switching rules above apply: the data being queried is whatever's in the active tab.
  2. Add Prefixes pastes in PREFIX lines for every prefix declared in your data, so you needn't type them.
  3. Execute Query runs it. Clear Results tidies up afterwards.
  4. Export Query saves the query text as query.sparql.

What you can ask

The engine (Comunica) speaks SPARQL 1.2, so everything from 1.1 plus the newer additions:

Reading the results

SELECT answers appear as a table. Language-tagged text shows its tag (hello@en, or مرحبا@ar--rtl when it has a direction) and a triple term is written out as <<( s p o )>>.

Export Results offers CSV or JSON for a table. The JSON follows the SPARQL 1.2 results format, so other 1.2-aware tools can read it, triple terms and all. For a graph result it saves Turtle as results.ttl.

Graph results (CONSTRUCT and DESCRIBE)

A graph result comes back as Turtle, written with the prefixes from your data, duplicates removed, and only the prefixes it actually uses declared at the top.

Where it goes depends on the Graph results to tab box among the SPARQL buttons:

Either way Export Results still saves it.

Why did my query return nothing? (Explain)

An empty table is the hardest result to read: it looks the same whether the data has no answer, a predicate is misspelled, or a FILTER threw everything away. Explain, next to Execute Query, answers it.

It shows the query plan: the steps the engine took, with the number of rows each one produced and how long it took. The diagram pane draws it as a tree with rows flowing upward from the bottom, and the results pane lists the same thing as a table.

What to look for is the step where the rows ran out. Reading from the bottom:

QuadPattern(?shop rdf:type bs:Bookshop)      33 rows    2 ms
QuadPattern(?shop rdfs:label ?shop_name)    507 rows    4 ms
  LeftJoin(keys = ?shop)                     33 rows
QuadPattern(?shop bs:inSettlement ?s)         0 rows    0 ms
  LeftJoin(keys = ?shop)                      0 rows   <- nothing came out of here

33 bookshops were found, then a pattern matched nothing, and from there the query had no answer. The culprit is bs:inSettlement, a predicate that isn't in the data. The app marks that step in red, in both the diagram and the table, and says so in a line above the table, so you don't have to spot it yourself.

The same view shows the opposite problem: a step whose row count is far larger than its neighbours' is where a query got slow, usually a join with nothing to constrain it.

Three things to know:

Things that catch people out

5. Validating with SHACL

SHACL is the other way to ask a question of your data: instead of a query that returns rows, a set of shapes that say what well-formed data looks like, and a report of everywhere the data falls short. The editor runs a full SHACL engine in the browser (the same one behind holos, compiled to WebAssembly): SHACL Core and SHACL-SPARQL, so sh:sparql constraints and SPARQL-based targets work too, and it reads RDF 1.2 data.

Running a validation

  1. Have the data in one tab and the shapes in another. Click + in the tab strip for a new tab, then Open File or Load URL into it. Or open the page with both in the address: ?dot=<data url>&shapes=<shapes url> loads the shapes into their own tab and picks it for you.
  2. Switch to the data tab. Validation always checks the tab in front.
  3. In the Shapes dropdown at the right of the panel's buttons, choose the tab holding the shapes. It gets a small shapes badge in the tab strip so you can see which is which.
  4. Click Validate. The first click also loads the engine, about a megabyte; after that it's instant.

Reading the report

The headline says Conforms or Does not conform, with the number of violations, warnings and infos and how many shapes were checked. Under it, one row per result:

Report as tab opens the report itself as a new tab. It's an RDF graph (sh:ValidationReport, sh:ValidationResult), so you can draw it, query it (SELECT ?focus WHERE { ?r sh:focusNode ?focus }) or save it. Export report saves it straight to validation-report.ttl. Clear puts the panel back.

Trying it

The SPARQL course ships shapes.ttl and shapes-advanced.ttl. Load bookshop-trail-1.1.ttl as data and shapes.ttl as shapes, validate, then change a shop's bs:staffCount to 0 and validate again: one new violation, "Staff count must be a positive integer", pointing at that shop.

Things that catch people out

6. RDF 1.2 and SPARQL 1.2

The parser (n3.js 2.2) and the query engine (Comunica 5.3) both speak the 1.2 versions of the standards, and the app has been checked against each feature below. Here's what you can rely on, and what to watch for.

What works

What doesn't, yet

7. Advanced Features

Reasoning (Hylar)

There's a built-in OWL 2 RL reasoner. Click Show Facts in the Graph toolbar and a new window lists the explicit triples (the ones in your data) and the implicit ones the reasoner worked out from them.

Format conversion

To Turtle and To JSON-LD in the Graph toolbar rewrite the active tab's data in that format, in place.

URL parameters

Add these to the page address to open it with data already loaded:

Remember to URL-encode the address you pass in.

8. Security and privacy

This tool is built so that it can be used with data you'd rather not send anywhere. Here is exactly what that means, in plain terms, so you can decide for yourself.

Everything runs in the page

The Turtle parser, the Graphviz renderer, the SPARQL engine (Comunica), the reasoner (Hylar) and the SHACL engine (a WebAssembly build of holos) all run inside your browser tab. They're served from the same place as the page itself, never from a content-delivery network, and none of them phones home. There's no analytics, no telemetry, no crash reporting, and no "look up this prefix online" convenience. The one such lookup a library used to carry (prefix.cc, inside a serialiser this app never calls) has been cut out of the build altogether.

The only things that leave the browser, and only when you ask

That's the whole list. In particular:

The browser enforces it

The page carries a Content Security Policy, so the rules above aren't just good intentions. Scripts run only from the page's own origin: no inline scripts, no javascript: links, no eval. The page may connect only to its own origin and to HTTP(S) addresses, which is what Load URL and SERVICE need. If a future change, or a bug, tried to load a script from elsewhere or run code smuggled in through a data file, the browser would refuse and say so in the console.

Data can't run code, either. Everything that comes from a file, IRIs, labels, literal text, is drawn, listed and printed as text. A literal containing <script> or <img onerror=…> is just an ugly string.

If you're deploying this inside an organisation

Things worth knowing