sheet 2 RDF
sheet 2 RDF#
GenDifS wurde entworfen zur grafischen Modellierung einer Taxonomie, die dann als OWL T-Box und als SKOS-Thesaurus exportiert werden kannn.
Konzeptionell nicht vorgesehen ist GenDifS dagegen zur Modellierung einer A-Box, d.h. eines Netzwerks von Instanzen (gelegentlich auch Knowledge Graph genannt). Wenn gewünscht ist, dass eine in GenDifS modellierte Taxonomie auch mit Instanzen angereichert wird, muss diese Anreicherung auf einem anderen Weg erfolgen.
In der Praxis üblich ist es, Datensätze “zeilenweise” in (meistens Excel-, im Linked Open Data (LOD) Umfeld besser CSV-) Tabellen vorzuhalten. Da eine Excel- oder CSV-Datei einzulesen nicht immer trivial ist, gehen wir im folgenden davon aus, dass Daten bereits erfolgreich als Pandas Dataframe eingelesen wurden. Damit können wir den GenDifS Instanz-Import auch für alle anderen Datenformate einsetzen, für die es einen Import in ein Dataframe gibt.
GenDifS kann Daten aus einem Pandas Dataframe als Instanzen wie folgt einlesen:
TBD: beschreiben!
import sys
sys.path.append('../py/')
from gd06 import GenDifS_Map
Im folgenden aus https://w3c.github.io/csvw/csv2rdf/ das Beispiel 3: http://example.org/countries.csv:
# Dateiname für Mindmap, sheet etc.
example_3 = "countries"
import pandas as pd
df = pd.read_csv(f"../sheets/{example_3}.csv", dtype=str)
#df.reset_index(inplace=True) # do we really need an explicit index column?
#df['index_str'] = df.index.map(str)
df
countryCode | latitude | longitude | name | |
---|---|---|---|---|
0 | AD | 42.5 | 1.6 | Andorra |
1 | AE | 23.4 | 53.8 | United_Arab_Emirates |
2 | AF | 33.9 | 67.7 | Afghanistan |
df.columns
Index(['countryCode', 'latitude', 'longitude', 'name'], dtype='object')
backup_mindmap = False
update_mindmap = True
# Mindmap und Sheet einlesen
o = GenDifS_Map(f"../mm/{example_3}.mm",
# sheet = f"../sheets/{example_3}.csv", # 2023-07-30: DEPRECATED
sheet_df = df,
pattern= ["owl", "a-box"],
# use_rdflib = False,
# remove_attributes= False, # default: true
verbose = 1)
__init__: GenDifS 0.63 (2023-08-01, 2023-09-08)
# Lexikalische Analyse, Parser, OWL-Code erzeugen
o.compile()
lexer: Lexer: found #1 start nodes: ['TAXONOMY']
codegen: codegen: generated 4 entries in `ttl_records`
get_code: Collected 12 code lines, pattern: ['owl', 'a-box', 'ALL']
rdflib_parse: rdflib: 21 triples.
o.owlrl()
owlrl: owlrl: 171 triples.
print(o.show_log(verbose=1))
GenDifS 0.63 (2023-08-01, 2023-09-08)
Lexer: found #1 start nodes: ['TAXONOMY']
codegen: generated 4 entries in `ttl_records`
Collected 12 code lines, pattern: ['owl', 'a-box', 'ALL']
rdflib: 21 triples.
owlrl: 171 triples.
So sieht die eingelesene CSV-Datei aus. Wir sehen, dass das eine “Tabelle” ist, genauer: Eine zeilenweise notiere Relation:
o.sheet_df
countryCode | latitude | longitude | name | |
---|---|---|---|---|
0 | AD | 42.5 | 1.6 | Andorra |
1 | AE | 23.4 | 53.8 | United_Arab_Emirates |
2 | AF | 33.9 | 67.7 | Afghanistan |
So sieht unsere Mindmap aus:
o.display_markdown()
TAXONOMY
countryCode COL
DP latitude COL
DP longitude COL
REL name
Das ist der Graph (die T-Box und die A-Box) im Format TTL, das von GenDifS erzeugt wird:
print(o.ttl_code)
# __init__
# ALL:
@prefix ex: <http://example.net/namespace/ex#> .
@prefix cpt: <http://example.net/namespace/cpt#> .
@prefix sheet: <http://example.net/namespace/sheet#> .
@prefix : <http://example.net/namespace/default#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xml: <http://www.w3.org/XML/1998/namespace> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix gendifs: <http://jbusse.de/gendifs#> .
# __init__
# ALL:
[ rdf:type owl:Ontology ] .
# SUBTAXON.TAXONOMY.a
# owl: declare class *countryCode* being a subclass of topConcept
:countryCode
a owl:Class ;
rdfs:subClassOf :topConcept .
# A-Box.SUBTAXON.TAXONOMY.d
# a-box:
sheet:AD
a :countryCode .
sheet:AE
a :countryCode .
sheet:AF
a :countryCode .
# DP.a
# owl: declare *latitude* as a data property.
:latitude
rdf:type owl:DatatypeProperty ;
rdf:label "latitude" .
# A-Box.DP.c
# a-box:
sheet:AD :latitude "42.5" .
sheet:AE :latitude "23.4" .
sheet:AF :latitude "33.9" .
# A-Box.DP.c
# a-box:
sheet:AD :latitude "42.5" .
sheet:AE :latitude "23.4" .
sheet:AF :latitude "33.9" .
# DP.a
# owl: declare *longitude* as a data property.
:longitude
rdf:type owl:DatatypeProperty ;
rdf:label "longitude" .
# A-Box.DP.c
# a-box:
sheet:AD :longitude "1.6" .
sheet:AE :longitude "53.8" .
sheet:AF :longitude "67.7" .
# A-Box.DP.c
# a-box:
sheet:AD :longitude "1.6" .
sheet:AE :longitude "53.8" .
sheet:AF :longitude "67.7" .
# REL.a
# owl: declare *name* as a object property.
:name
rdf:type owl:ObjectProperty ;
rdf:label "name" .
# A-Box.REL.c
# a-box:
sheet:AD :name sheet:Andorra .
sheet:AE :name sheet:United_Arab_Emirates .
sheet:AF :name sheet:Afghanistan .
with open(f"../ttl/{example_3}_mm.ttl", "w") as file:
file.write(o.ttl_code)
if update_mindmap:
update_mindmap_filename = f"../mm/{example_3}.mm"
o.mindmap.write(update_mindmap_filename,pretty_print=True)
print(f"updated mindmap {update_mindmap_filename}")
updated mindmap ../mm/countries.mm
Selbstverständlich kann man diesen Graphen auch als json exportieren (hier nur die ersten 500 Zeichen):
print(o.rdflib_graph.serialize(format="json-ld")[:500])
[
{
"@id": "http://example.net/namespace/default#name",
"@type": [
"http://www.w3.org/2002/07/owl#ObjectProperty"
],
"http://www.w3.org/1999/02/22-rdf-syntax-ns#label": [
{
"@value": "name"
}
]
},
{
"@id": "_:n673d4ae2fa7b41d7a81718f33e7a13c4b1",
"@type": [
"http://www.w3.org/2002/07/owl#Ontology"
]
},
{
"@id": "http://example.net/namespace/sheet#AF",
"@type": [
"http://example.net/namespace/default#countryCo