Last active
July 24, 2018 07:00
-
-
Save boutros/f99baa0c2d3c17b4a73f4fc26faa6119 to your computer and use it in GitHub Desktop.
shacl2dot
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@base <https://tjenester.deichman.no/ontology/> . | |
@prefix sh: <http://www.w3.org/ns/shacl#> . | |
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . | |
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . | |
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . | |
<ServiceShape> | |
a sh:NodeShape ; | |
sh:targetClass <Service> ; | |
sh:name "Tjeneste"@no ; | |
sh:property [ | |
sh:name "Bilde"@no ; | |
sh:path <image> ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:nodeKind sh:IRI | |
] ; | |
sh:property [ | |
sh:path <name> ; | |
sh:name "Navn"@no ; | |
sh:minCount "1"^^xsd:integer ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:datatype xsd:string | |
] ; | |
sh:property [ | |
sh:name "Tjenestetype"@no ; | |
sh:path <serviceType> ; | |
sh:minCount "1"^^xsd:integer ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:class <ServiceType> | |
] ; | |
sh:property [ | |
sh:name "Tjenesteform"@no ; | |
sh:path <serviceForm> ; | |
sh:minCount "1"^^xsd:integer ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:class <ServiceForm> | |
] ; | |
sh:property [ | |
sh:name "Status"@no ; | |
sh:path <status> ; | |
sh:minCount "1"^^xsd:integer ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:class <Status> | |
] ; | |
sh:property [ | |
sh:name "Aldersgrupper"@no ; | |
sh:path <ageGroup> ; | |
sh:minCount "1"^^xsd:integer ; | |
sh:class <AgeGroup> | |
] ; | |
sh:property [ | |
sh:name "Målgrupper"@no ; | |
sh:path <targetAudience> ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:class <TargetAudience> | |
] ; | |
sh:property [ | |
sh:name "Beskrivelse eksternt"@no ; | |
sh:path <descriptionExternal> ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:datatype xsd:string | |
] ; | |
sh:property [ | |
sh:name "Beskrivelse eksternt"@no ; | |
sh:path <descriptionInternal> ; | |
sh:minCount "1"^^xsd:integer ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:datatype xsd:string | |
] ; | |
sh:property [ | |
sh:path <recommendedFrequency> ; | |
sh:name "Anbefalt hyppighet"@no ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:class <Frequency> | |
] ; | |
sh:property [ | |
sh:path <successCriteria> ; | |
sh:name "Suksesskriterier"@no ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:datatype xsd:string | |
] ; | |
sh:property [ | |
sh:path <standard> ; | |
sh:name "Standard"@no ; | |
sh:minCount "1"^^xsd:integer ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:datatype xsd:boolean | |
] ; | |
sh:property [ | |
sh:name "Navn på lenke"@no ; | |
sh:path <link> ; | |
sh:class <Link> | |
] ; | |
sh:property [ | |
sh:path <extendedUsage> ; | |
sh:name "Passer i spesialtid"@no ; | |
sh:class <ExtendedUsage> | |
] ; | |
sh:property [ | |
sh:path <season> ; | |
sh:name "Sesong"@no ; | |
sh:class <Season> | |
] ; | |
sh:property [ | |
sh:path <tag> ; | |
sh:name "Triggerord"@no ; | |
sh:datatype xsd:string | |
] ; | |
sh:property [ | |
sh:path <contentElement> ; | |
sh:name "Innholdselementer"@no ; | |
sh:class <ContentElement> | |
] ; | |
sh:property [ | |
sh:name "Hensikt, mål og ønsket effekt"@no ; | |
sh:path <expectedEffect> ; | |
sh:minCount "1"^^xsd:integer ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:datatype xsd:string | |
] ; | |
sh:property [ | |
sh:name "Innsatsområder"@no ; | |
sh:path <targetArea> ; | |
sh:minCount "1"^^xsd:integer ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:class <TargetArea> | |
] ; | |
sh:property [ | |
sh:name "Livsløp"@no ; | |
sh:path <lifecycle> ; | |
sh:minCount "1"^^xsd:integer ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:class <Lifecycle> | |
] ; | |
sh:property [ | |
sh:name "Tjenesteeier"@no ; | |
sh:path <serviceOwner> ; | |
sh:minCount "1"^^xsd:integer ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:datatype xsd:string | |
] ; | |
sh:property [ | |
sh:name "Produktansvarlig"@no ; | |
sh:path <productResponsibleStaff> ; | |
sh:minCount "1"^^xsd:integer ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:datatype xsd:string | |
] ; | |
sh:property [ | |
sh:name "Lokalansvarlig"@no ; | |
sh:description "Ansvarsperson(er) på filial"@no ; | |
sh:path <localResponsible> ; | |
sh:class <Responsible> | |
] ; | |
sh:property [ | |
sh:name "Regi"@no ; | |
sh:path <direction> ; | |
sh:minCount "1"^^xsd:integer ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:class <Direction> | |
] ; | |
sh:property [ | |
sh:name "Samarbeidspartnere"@no ; | |
sh:path <partner> ; | |
sh:class <Partner> | |
] ; | |
sh:property [ | |
sh:name "Finansiering"@no ; | |
sh:path <funding> ; | |
sh:datatype xsd:string | |
] ; | |
sh:property [ | |
sh:name "Forbredelsestid (antall timer)"@no ; | |
sh:path <preparationHours> ; | |
sh:minCount "1"^^xsd:integer ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:datatype xsd:integer | |
] ; | |
sh:property [ | |
sh:name "Gjennomføringsressurser (antall personer)"@no ; | |
sh:path <requiredStaff> ; | |
sh:minCount "1"^^xsd:integer ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:datatype xsd:integer | |
] ; | |
sh:property [ | |
sh:name "Andre kostnader gjennomføring"@no ; | |
sh:path <costs> ; | |
sh:datatype xsd:string | |
] . | |
<ServiceTypeShape> | |
a sh:NodeShape ; | |
sh:name "Tjenestetype"@no ; | |
sh:targetClass <ServiceType> ; | |
sh:property [ | |
sh:name "Navn"@no ; | |
sh:path <name> ; | |
sh:minCount "1"^^xsd:integer ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:datatype xsd:string | |
] . | |
<ServiceFormShape> | |
a sh:NodeShape ; | |
sh:name "Tjenesteform"@no ; | |
sh:targetClass <ServiceForm> ; | |
sh:property [ | |
sh:name "Navn"@no ; | |
sh:path <name> ; | |
sh:minCount "1"^^xsd:integer ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:datatype xsd:string | |
] . | |
<StatusShape> | |
a sh:NodeShape ; | |
sh:name "Status"@no ; | |
sh:targetClass <Status> ; | |
sh:property [ | |
sh:name "Navn"@no ; | |
sh:path <name> ; | |
sh:minCount "1"^^xsd:integer ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:datatype xsd:string | |
] . | |
<AgeGroupShape> | |
a sh:NodeShape ; | |
sh:name "Aldersgruppe"@no ; | |
sh:targetClass <AgeGroup> ; | |
sh:property [ | |
sh:name "Navn"@no ; | |
sh:path <name> ; | |
sh:minCount "1"^^xsd:integer ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:datatype xsd:string | |
] ; | |
sh:property [ | |
sh:name "Fra og med år"@no ; | |
sh:path <fromYear> ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:datatype xsd:integer | |
] ; | |
sh:property [ | |
sh:name "Til og med år"@no ; | |
sh:path <toYear> ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:datatype xsd:integer | |
] . | |
<TargetAudienceShape> | |
a sh:NodeShape ; | |
sh:name "Målgruppe"@no ; | |
sh:targetClass <TargetAudience> ; | |
sh:property [ | |
sh:name "Navn"@no ; | |
sh:path <name> ; | |
sh:minCount "1"^^xsd:integer ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:datatype xsd:string | |
] ; | |
sh:property [ | |
sh:name "Beskrivelse"@no ; | |
sh:path <description> ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:datatype xsd:string | |
] . | |
<FrequencyShape> | |
a sh:NodeShape ; | |
sh:name "Hyppighet"@no ; | |
sh:targetClass <Frequency> ; | |
sh:property [ | |
sh:name "Navn"@no ; | |
sh:path <name> ; | |
sh:minCount "1"^^xsd:integer ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:datatype xsd:string | |
] . | |
<LinkShape> | |
a sh:NodeShape ; | |
sh:name "Lenke"@no ; | |
sh:targetClass <Link> ; | |
sh:property [ | |
sh:name "Navn"@no ; | |
sh:path <name> ; | |
sh:minCount "1"^^xsd:integer ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:datatype xsd:string | |
] . | |
<ExtendedUsageShape> | |
a sh:NodeShape ; | |
sh:name "Spesialtid"@no ; | |
sh:targetClass <ExtendedUsage> ; | |
sh:property [ | |
sh:name "Navn"@no ; | |
sh:path <name> ; | |
sh:minCount "1"^^xsd:integer ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:datatype xsd:string | |
] . | |
<SeasonShape> | |
a sh:NodeShape ; | |
sh:name "Sesong"@no ; | |
sh:targetClass <Season> ; | |
sh:property [ | |
sh:name "Navn"@no ; | |
sh:path <name> ; | |
sh:minCount "1"^^xsd:integer ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:datatype xsd:string | |
] . | |
<ContentElementShape> | |
a sh:NodeShape ; | |
sh:name "Innholdselement"@no ; | |
sh:targetClass <ContentElement> ; | |
sh:property [ | |
sh:name "Navn"@no ; | |
sh:path <name> ; | |
sh:minCount "1"^^xsd:integer ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:datatype xsd:string | |
] ; | |
sh:property [ | |
sh:name "Beskrivelse"@no ; | |
sh:path <description> ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:datatype xsd:string | |
] ; | |
sh:property [ | |
sh:name "Bibliotek"@no ; | |
sh:path <branch> ; | |
sh:class <Branch> | |
] . | |
<BranchShape> | |
a sh:NodeShape ; | |
sh:name "Bibliotek"@no ; | |
sh:targetClass <Branch> ; | |
sh:property [ | |
sh:name "Navn"@no ; | |
sh:path <name> ; | |
sh:minCount "1"^^xsd:integer ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:datatype xsd:string | |
] ; | |
sh:property [ | |
sh:name "Service"@no ; | |
sh:path <service> ; | |
sh:class <Service> | |
] . | |
<TargetAreaShape> | |
a sh:NodeShape ; | |
sh:name "Innsatsområde"@no ; | |
sh:targetClass <TargetArea> ; | |
sh:property [ | |
sh:name "Navn"@no ; | |
sh:path <name> ; | |
sh:minCount "1"^^xsd:integer ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:datatype xsd:string | |
] . | |
<LifecycleShape> | |
a sh:NodeShape ; | |
sh:name "Livsløp"@no ; | |
sh:targetClass <Lifecycle> ; | |
sh:property [ | |
sh:name "Navn"@no ; | |
sh:path <name> ; | |
sh:minCount "1"^^xsd:integer ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:datatype xsd:string | |
] ; | |
sh:property [ | |
sh:name "Beskrivelse"@no ; | |
sh:path <description> ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:datatype xsd:string | |
] . | |
<ResponsibleShape> | |
a sh:NodeShape ; | |
sh:name "Ansvarlig ansatt"@no ; | |
sh:targetClass <Responsible> ; | |
sh:property [ | |
sh:name "Navn"@no ; | |
sh:path <name> ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:datatype xsd:string | |
] ; | |
sh:property [ | |
sh:name "Bibliotek/avdeling"@no ; | |
sh:minCount "1"^^xsd:integer ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:path <branch> ; | |
sh:class <Branch> | |
] . | |
<DirectionShape> | |
a sh:NodeShape ; | |
sh:name "Regi"@no ; | |
sh:targetClass <Direction> ; | |
sh:property [ | |
sh:name "Navn"@no ; | |
sh:path <name> ; | |
sh:minCount "1"^^xsd:integer ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:datatype xsd:string | |
] . | |
<PartnerShape> | |
a sh:NodeShape ; | |
sh:name "Partner"@no ; | |
sh:targetClass <Partner> ; | |
sh:property [ | |
sh:name "Navn"@no ; | |
sh:path <name> ; | |
sh:minCount "1"^^xsd:integer ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:datatype xsd:string | |
] ; | |
sh:property [ | |
sh:name "Målgruppe"@no ; | |
sh:path <audience> ; | |
sh:maxCount "1"^^xsd:integer ; | |
sh:datatype xsd:string | |
] . |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"io" | |
"log" | |
"os" | |
"strings" | |
"github.com/knakk/kbp/rdf" | |
) | |
var prefixes = strings.NewReplacer("http://www.w3.org/2001/XMLSchema#", "xsd:", "<", "", ">", "") | |
type NodeShape struct { | |
Class string | |
Name string | |
Literals []Literal | |
} | |
type Literal struct { | |
Name string | |
Path string | |
Datatype string | |
Class string | |
MustHaveOne bool | |
CanHaveMore bool | |
} | |
func (l Literal) String() string { | |
must := " " | |
can := " " | |
if l.MustHaveOne { | |
must = "*" | |
} | |
if l.CanHaveMore { | |
must = "+" | |
} | |
return fmt.Sprintf("%s%s <b>%s</b> (%s)", must, can, l.Name, l.Datatype) | |
} | |
type Link struct { | |
From string | |
To string | |
Name string | |
Path string | |
MustHaveOne bool | |
CanHaveMore bool | |
} | |
func (l Link) String() string { | |
must := " " | |
can := " " | |
if l.MustHaveOne { | |
must = "*" | |
} | |
if l.CanHaveMore { | |
must = "+" | |
} | |
return fmt.Sprintf("%s%s <b>%s</b>", must, can, l.Name) | |
} | |
func main() { | |
f, err := os.Open("schema.ttl") | |
if err != nil { | |
log.Fatal(err) | |
} | |
defer f.Close() | |
dec := rdf.NewDecoder(f) | |
nodes := make(map[rdf.Node]NodeShape) | |
var links []Link | |
var curNode rdf.Node | |
var curLiteral *Literal | |
for tr, err := dec.Decode(); err != io.EOF; tr, err = dec.Decode() { | |
if err != nil { | |
log.Fatal(err) | |
} | |
switch tr.Predicate { | |
case rdf.RDFtype: | |
if curLiteral != nil { | |
if curLiteral.Class == "" { | |
n := nodes[curNode] | |
n.Literals = append(n.Literals, *curLiteral) | |
nodes[curNode] = n | |
} else { | |
links = append(links, Link{Path: curLiteral.Path, From: nodes[curNode].Class, To: curLiteral.Class, Name: curLiteral.Name, MustHaveOne: curLiteral.MustHaveOne, CanHaveMore: curLiteral.CanHaveMore}) | |
} | |
} | |
curLiteral = nil | |
curNode = tr.Subject | |
if _, ok := nodes[curNode]; !ok { | |
nodes[curNode] = NodeShape{} | |
} | |
case rdf.SHclass: | |
curLiteral.Class = tr.Object.String() | |
case rdf.SHpath: | |
curLiteral.Path = tr.Object.String() | |
case rdf.SHtargetClass: | |
n := nodes[curNode] | |
n.Class = tr.Object.String() | |
nodes[curNode] = n | |
case rdf.SHproperty: | |
if curLiteral != nil { | |
if curLiteral.Class == "" { | |
n := nodes[curNode] | |
n.Literals = append(n.Literals, *curLiteral) | |
nodes[curNode] = n | |
} else { | |
links = append(links, Link{Path: curLiteral.Path, From: nodes[curNode].Class, To: curLiteral.Class, Name: curLiteral.Name, MustHaveOne: curLiteral.MustHaveOne, CanHaveMore: curLiteral.CanHaveMore}) | |
} | |
} | |
curLiteral = &Literal{ | |
CanHaveMore: true, | |
} | |
case rdf.SHname: | |
if curLiteral == nil { | |
n := nodes[curNode] | |
n.Name = tr.Object.(rdf.Literal).ValueAsString() | |
nodes[curNode] = n | |
} else { | |
curLiteral.Name = tr.Object.(rdf.Literal).ValueAsString() | |
} | |
case rdf.SHminCount: | |
curLiteral.MustHaveOne = true | |
case rdf.SHMaxCount: | |
curLiteral.CanHaveMore = false | |
case rdf.SHdatatype: | |
curLiteral.Datatype = prefixes.Replace(tr.Object.String()) | |
default: | |
} | |
} | |
//fmt.Println(nodes) | |
//fmt.Println("") | |
//fmt.Println(links) | |
if curLiteral != nil { | |
if curLiteral.Class == "" { | |
n := nodes[curNode] | |
n.Literals = append(n.Literals, *curLiteral) | |
nodes[curNode] = n | |
} else { | |
links = append(links, Link{From: nodes[curNode].Class, To: curLiteral.Class, Name: curLiteral.Name, MustHaveOne: curLiteral.MustHaveOne, CanHaveMore: curLiteral.CanHaveMore}) | |
} | |
curLiteral = nil | |
} | |
fmt.Printf(`digraph Ontology { | |
graph [overlap=voronoi, ranksep=1.3, splines=curved] | |
node [shape=plaintext fontname="Sans serif" fontsize="8"]; | |
edge [fontname="Sans serif", fontsize="8"]; | |
`) | |
for _, node := range nodes { | |
fmt.Printf(` %s [label=< | |
<table border="1" cellborder="0" cellspacing="1" width="100"> | |
<tr><td bgcolor='#e0e0e0'>%s</td><td bgcolor='#e0e0e0'><b>%s</b></td></tr> | |
`, strip(node.Class), escape(node.Class), node.Name) | |
for _, lit := range node.Literals { | |
fmt.Printf(` <tr><td align="left">%s</td><td align="left">%s</td></tr> | |
`, escape(lit.Path), lit.String()) | |
} | |
fmt.Printf(`</table>>]; | |
`) | |
} | |
for _, link := range links { | |
if link.From == "" || link.To == "" { | |
continue | |
} | |
fmt.Printf("%s -> %s [label=<%s>];\n", strip(link.From), strip(link.To), link.String()) | |
} | |
fmt.Println(`}`) | |
} | |
func strip(s string) string { | |
return s[1 : len(s)-1] | |
} | |
func escape(s string) string { | |
return "<" + strip(s) + ">" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment