Example: HelloWorldWrite.go
You might use an IDE (Integrated Development Environment) such as VSC (Visual Studio Code) to develop an SST application.
Let’s create Hello World Write example to generate some RDF data.
Golang IDEs such as VSC manages the needed imports automatically; so user don’t need worry about these. However there is one exception with “git.semanticstep.net/x/sst/vocabularies/dict”. This package contains essential initialisation code for the default vocabularies/dictionaries used by SST. To enforce proper initialisation of this package it has to be entered manually with a leading _ that will prevent that this manually enterned import is not taken away as it is not referenced in the code. So for this example we’ll get at the end these imports:
package main
import (
"fmt"
"log"
"os"
"git.semanticstep.net/x/sst/sst"
_ "git.semanticstep.net/x/sst/vocabularies/dict"
"git.semanticstep.net/x/sst/vocabularies/lci"
"git.semanticstep.net/x/sst/vocabularies/rdfs"
"github.com/google/uuid"
)
The first thing in an SST application is to create a stage in which we are going to create the nodes and triples. For this example we are using a new empty ephemeral stage that is not bound to any existing [Repository] and [Dataset]; so the data we are going to create can not directly be committed into a SST Repository.
func main() {
fmt.Println("HelloWorldWrite ... ")
stage := sst.OpenStage(sst.DefaultTriplexMode)
A stage contains NamedGraphs where one NamedGraph may import other NamedGraph, forming a directed acyclic graphs of NamedGraphs. Let’s create a new single NamedGraph that is identified by a random UUID-URN (version 4).
graph := stage.CreateNamedGraphByUUID(uuid.New())
fmt.Println("URI of NamedGraph = " + graph.IRI())
The resulting NamedGraph might e.g. have the URI urn:uuid:a8f3dc19-68f5-44d1-97bc-21ba2d8a6037
ib := graph.CreateIRINode(uuid.New().String(), lci.Individual)
fmt.Println("IRI of IRI node = " + ib.IRI())
fmt.Println("Fragment of IRI node = " + ib.Fragment())
Next we create a new IRI node in the NamedGraph together with a first triple to specifiy it’s rdf:type.
In this case the node is identified by a fragment that contains a random-UUID within the NamedGraph. E.g. the UUID of the fragment is 6d52b623-f933-4c26-ba18-164a6cc50ae8, and so the complete IRI of the node is e.g. urn:uuid:a8f3dc19-68f5-44d1-97bc-21ba2d8a6037#6d52b623-f933-4c26-ba18-164a6cc50ae8. Note that this IRI contains 2 different UUIDs, one for the NamedGraph, and one for the fragment of the node in that NamedGraph. An IBNode can exist in a NamedGraph only when it has at least one subject triple; so here we say it has the type lci.Individual.
ib := graph.CreateIRINode(uuid.New().String(), lci.Individual)
with AddStatement we can add further triples
ib.AddStatement(rdfs.Label, sst.String("HelloWorld"))
// Next we create a triple (s statement) with:
// * subject: the IRI node we created
// * predicate: rdf:type
// * object : an lci:individual, that is a concept of the life-cycle integration ontology on which SST is based on.
// the created graph can be exported into a Turtle (*.ttl) file that has a readable text representation
f, err := os.Create("helloworldwrite.ttl")
if err != nil {
panic(err)
}
defer f.Close()
err = graph.RdfWrite(f, sst.RdfFormatTurtle)
if err != nil {
log.Panic(err)
}
// alternatively the created graph can be exported into a binary SST file that is much faster to process compared to turtle.
// for this we first create a file ...
out, err := os.Create("helloworldwrite.sst")
if err != nil {
log.Panic(err)
}
// ... ensure that the file will be closed at the end ...
defer func() {
_ = out.Close()
}()
// ... and write the binary graph content out into the file.
err = graph.SstWrite(out)
if err != nil {
log.Panic(err)
}
fmt.Printf("Done\n")
}