Von Excel zu Turtle With NodeJS

Wenn die meisten Leute über die Daten eines Unternehmens nachdenken, stellen sie sich wahrscheinlich irgendwo eine große Serverfarm mit Terabytes an Daten in riesigen relationalen Datenbanken vor. Eine überraschende (sogar störende) Menge der Metadaten in dieser Organisation wird dort wahrscheinlich nicht gespeichert, sondern wurde im Laufe der Jahre in Microsoft Excel oder seinen vielen, vielen Derivaten erstellt (und verwaltet). Dies sind in der Regel auch Informationen, für die semantische Dreifachspeicher und Metadaten-Hubs ideal geeignet sind – kontrollierte Vokabulare, Datenwörterbücher, zusammenfassende Analysen usw.

Es gibt jedoch ein p r -Oblem mit Excel als Datenquelle. Eine Excel-Arbeitsmappe ist im Wesentlichen ein Buch mit Arbeitsblättern, die selbst Raster sind. Es gibt dort keine Vererbungsstruktur, kein echtes Schema, abgesehen von den manchmal obskuren Designs, die sich der Tabellenkalkulationsersteller ad hoc zugewiesen hat. Dies bedeutet, dass, wenn Sie einem Ontologen oder Aufnahmeingenieur eine Excel-Tabelle geben, es keine magische Schaltfläche gibt, die er drücken kann, um diese Struktur zu verwischen. Die Struktur muss forensisch ausgearbeitet werden. Dies bedeutet, dass Sie, wenn Sie Excel auf diese Weise verwenden möchten, eine solche Reihenfolge im Voraus festlegen müssen.

Zelle als Dreifach

Aus semantischer Sicht gibt es zwei Ansätze, mit denen Sie solche Tabellen in RDF-Daten konvertieren können. Im ersten Schritt suchen Sie jede Zelle, in der sich Inhalt befindet, und erstellen dann eine URL, die den Speicherort der Zelle basierend auf der Tabelle, Zeile und Spalte widerspiegelt.

Wenn Sie beispielsweise eine Tabelle mit dem Namen myData.xls (oder eine ähnliche Erweiterung) hatten, kann die Zelle [B5] in „Meine Tabelle“ (mit dem Wert „Jane Doe“) wie folgt angegeben werden (angegeben als Schildkröte):

Dies ist eigentlich kein schlechter Ansatz, wenn die Struktur der Tabelle sowohl spärlich als auch sehr gut spezifiziert ist. Wenn diese Struktur jedoch nicht vorhanden ist und herausgearbeitet werden kann, ist es oft eine Menge Arbeit, die sich sonst nur wenig auszahlt. Die besten Anwendungsfälle gibt es, wenn Excel als Eingabeformular für Daten verwendet wird oder wenn es algorithmisch (möglicherweise als Bericht) generiert wird und die spezifische Struktur größtenteils bekannt ist. Oft ist es jedoch besser, einen der größeren Vorteile von Tabellenkalkulationen zu nutzen – die Zuordnung zwischen Arbeitsblättern und Tabellen.

Arbeitsblatt als Tabelle

Jeder, der über einen längeren Zeitraum mit Daten arbeitet, erkennt, dass eine Tabelle eine Tabelle ist. Sie können eine Tabelle als durch Kommas getrenntes Wertdokument (CSV, das eigentlich nicht ausschließlich durch Kommas getrennt werden muss) darstellen, wobei die erste Zeile die durch Trennzeichen getrennten Feldnamen und die zweite und nachfolgende Zeile die durch Trennzeichen getrennten Zeilenwerte enthält.

Eine relationale Datenbank macht fast genau das Gleiche und verwendet den Feldnamen als Proxy für die Feldposition (die wiederum für eine bestimmte Zeile auch die Feldposition für den Wert in dieser Zeile ist). Die meisten Datenbanken bieten auch einige schematische Metadaten (eine Schemadefinition oder DDL) zum Verwalten von Dingen wie Datentypdarstellung und Speicherkapazität für ein bestimmtes Feld. Die Tabelle hat auch einen Namen.

Ein Excel-Arbeitsblatt wie CSV funktioniert genauso: Die erste Zeile enthält Feldnamen und die nachfolgenden Zeilen enthalten die mit der Feldposition verknüpften Werte. Der Hauptunterschied besteht darin, dass der Tabellenname jetzt durch den Arbeitsblattnamen ersetzt wird und die Datenbank wiederum der Arbeitsmappe entspricht.

Interessant wird, dass dieselbe Korrespondenz in RDF auftritt. RDF ist eine normalisierte Datensprache – dies bedeutet, dass jede Hierarchie in flache Tabellen zerlegt wurde. In den einfachsten Fällen bedeutet dies auch, dass Sie eine Eins-zu-Eins-Entsprechung zwischen einer relationalen Datenbank, einer Tabelle und einer Reihe von Tripeln durchführen können, wobei die einzige Einschränkung bei letzteren darin besteht, dass Sie vorsichtig sein müssen, um globale Identifikationsschlüssel zu generieren (URIs oder IRIs), die aus den tabellarischen Informationen abgeleitet werden können.

Dies ist der Ansatz, den wir im aktuellen Artikel verfolgen werden.

Beschreibung eines NPC

Als ich jünger war, war ich ein begeisterter Rollenspieler (und natürlich ein Dungeon-Meister), der sich nicht nur wegen der Möglichkeit, meine Fantasie zu üben, für Spiele wie Dungeons and Dragons, Champions, GURPs usw. interessierte auch weil es so viele coole Tische in den Büchern gab, und als datengeeky Kind war das der Höhepunkt von Nerd-Dom. Infolgedessen ist es wahrscheinlich keine Überraschung, dass RPGs zu meinen bevorzugten Beispielen für die Präsentation von Datenmodellierung und -strukturen geworden sind, vor allem, weil sie komplex genug sind, um interessant, aber nicht so komplex zu sein, dass sie verwirrend sind, und weil ich sie nicht getroffen habe Ein Programmierer, der noch nicht mindestens ein Lieblings-RPG-Charakterblatt hat, das irgendwo in seinem hinteren Schrank herumschwirrt.

Um die Idee zu veranschaulichen (und um mit einigen Daten zu beginnen), habe ich eine Excel-Arbeitsmappe mit dem Namen Game.xlsx erstellt und einen beliebigen Satz von Beispielzeichen angelegt. Um das Formatieren zu vereinfachen, habe ich dies in mehrere Tabellen unterteilt:

Es ist erwähnenswert, dass dies nicht umfassend ist. Vielmehr reicht es gerade aus, verschiedene Muster bei der Herstellung von Tripeln zu präsentieren.

Die Aufschlüsselung in den obigen Tabellen ist nicht ganz zufällig. Der Name wird in allen Fällen als eindeutig angenommen – mit anderen Worten, er kann als Grundlage für einen Schlüssel dienen. Beachten Sie, dass dies für extern erfasste Datensätze nicht immer eine sichere Annahme ist. Mehrere Personen haben möglicherweise denselben Namen. Daher müssen möglicherweise andere Schlüssel (entweder einzeln oder kombiniert) verarbeitet werden, um eine eindeutige Kennung zu erstellen.

Die Techniken für die Schlüssel- (und letztendlich URI-) Generierung variieren, aber in den hier angegebenen Beispielen sind NPC-IDs am besten für das Namensattribut geeignet, normalerweise durch Komprimieren von Leerzeichen und anderen Interpunktionen aus dem Namen. Daher generiert „Mara GlynisDottir“ den Uri-Schlüssel npc: _MaraGlynisDottir . Es ist hier erwähnenswert, dass Sie, da das, was generiert wird, keine direkte Eins-zu-Eins-Darstellung einer Datenbank ist, sondern eher eine konzeptionelle Darstellung, den konzeptuellen Namespace angeben können, anstatt zu versuchen, a zu identifizieren gegebene Systemdatenbank. Wenn Sie jedoch einen URI basierend auf dem NPC basierend auf einer Systemkennung (hier System 125, bei dem es sich möglicherweise um eine Tabelle handelt) erstellen möchten, sieht dies möglicherweise folgendermaßen aus:

Der wichtige Punkt, an den Sie sich erinnern sollten, ist sicherzustellen, dass der Schlüssel global universell hergestellt werden kann. Wenn System 125 und System 130 jeweils ein Mara Glynisdottir haben, sollten sie als unterschiedliche Einheiten behandelt werden, bis sich herausstellt, dass sie höchstwahrscheinlich gleich sind (außerhalb des Geltungsbereichs dieses Artikels).

Zuordnungen treten häufig in Tabellenkalkulationen auf, in denen sie normalerweise eher als Namen als als Schlüssel angegeben werden. Diese fallen normalerweise in das, was oft als kontrolliertes Vokabular oder Kategoriebegriffe angesehen wird. Zum Beispiel hat das Geschlecht vier mögliche Kategorienbegriffe (hier „männlich“, „weiblich“, „androgyn“ und „nicht zutreffend“), die jeweils einem Geschlechtervokabular zugeordnet sind. Dies legt wiederum nahe, dass Sie zwar eine Tabelle nur für das Geschlecht, eine andere für Arten usw. erstellen können. Die Tatsache, dass dies alles Begriffe sind, die meist die gleichen relevanten Merkmale aufweisen, legt jedoch nahe, dass es besser ist, zwei Tabellen zu erstellen. eine für Vokabeln, eine zweite für Begriffe.

Im Tabellenkalkulationsbeispiel wurden dazu zwei weitere Arbeitsblätter mit Begriffen und Vokabeln als jeweiligen Registerkartennamen erstellt.

Die zweite Spalte des Term-Arbeitsblatts ist ein Vokabelname aus dem Vocab-Arbeitsblatt. Solange Sie sicherstellen können, dass die aus jeder dieser Tabellen erstellten Schlüssel miteinander und mit der NPC-Tabelle übereinstimmen, sollten Sie in der Lage sein, diese in Primärschlüssel- / Fremdschlüssel-Links umzuwandeln. Das vollständige Beispiel hier definiert achtzig Begriffe in sieben Vokabularen, obwohl es in einer realen Anwendung Dutzende bis Hunderte dieser Tabellen mit möglicherweise Zehntausenden von Klassifizierungskategorien geben kann. Solche Kategorien oder Assoziationen können auch als Facetten betrachtet werden, während Entitäten (wie NPCs) als Kombinationen von Facetten und entsprechenden Attributen (wie Namen oder Bewertungen) betrachtet werden können.

Die Attribute hingegen sind im Allgemeinen atomare Werte – Zeichenfolgen, Zahlen, Daten, was ein Wissenschaftler Skalare nennen würde. Es gab mindestens zwei Möglichkeiten, wie Attribute definiert werden konnten. Die erste wäre als spezifische Eigenschaften (wie Stärke oder Intelligenz) gewesen. Diese können wie folgt modelliert werden:

wobei es für jedes der Attribute eine bestimmte Eigenschaft (oder ein bestimmtes Prädikat) gibt, oder es könnte wie folgt modelliert worden sein:

wobei es nur ein Prädikat gibt (npc: hasAttribute) und dann einen Wert und einen zugehörigen Typ.

Aufgrund des Anwendungsdienstprogramms wurde das erste Formular bei Attributen bevorzugt (Sie vergleichen beispielsweise normalerweise bestimmte Attributwerte). cibstryct Der Nachteil dabei ist jedoch, dass Sie sich für den alternativen Ansatz entscheiden müssen, wenn Attribute keine spezifischen Skalare, sondern komplexere Strukturen sind. Vom Standpunkt der Modellierung aus können Sie eine Zuordnung zwischen einem bestimmten Attributprädikat und dem zugehörigen Typ erstellen:

Das Prädikat npc: hasStrength ist keine Unterklasse von npc: hasAttribute , da das erstere eine Dateneigenschaft ist, während das letztere eine Objekteigenschaft ist. aber es gibt eine Beziehung zwischen ihnen.

Die expansivere Form wird bei Münzen verwendet. Das Spiel hat fünf verschiedene Arten von Währungen, basierend auf dem Penny (im Wesentlichen dem Lohn, den ein Arbeiter für einen Arbeitstag verdienen würde). Eine Münze hat einen verallgemeinerten Wert (bezeichnet durch den Standardeigenschaftswert), wobei die kleinste Währung (ein Furz) ein Zwölftel eines Pennys (etwa eine Arbeitsstunde) ist und jede darüber liegende Einheit zwölfmal größer ist. Somit könnte das Gesamtvermögen eines Individuums bestimmt werden, indem die Anzahl der Münzen jedes Typs mit dem Standardwert für diesen Typ multipliziert wird. Dies ist eine Berechnung, die mit SPARQL durchgeführt werden kann. Da es sich um eine Metrik zur Bestimmung des Erfolgs im Spiel handelt, war es sinnvoll, vor Ort rechnen zu können. 25 Solad 14 Lunad 3 Crescent würde dann mit 5 * 123 + 14 * 122+ 3 * 12 oder 10.693 Pennys berechnet. In der Spielwelt sahen die meisten Bauern Solads im Allgemeinen nicht sehr oft, wie zu erwarten war.

Jede Münzsammlung wird dann durch eine Geldbörse dargestellt (also eine Geldbörse für Solads, eine für Lunads usw.). Eine Geldbörse würde wie folgt dargestellt:

und die Summe aller Geldbörsen für jeden NPC könnte wie folgt berechnet werden (SPARQL):

Die endgültige Tabelle, die im Excel-Dokument erstellt werden müsste, ist die Tabelle “ Namespaces “. Diese Tabelle stimmt mit dem Präfix mit dem Namespace und einer Beschreibung überein:

mit der Absicht, dass sich beide auf Turtle / Sparql konzentrieren. Im ersten Fall kann sichergestellt werden, dass Namespaces lokal identifiziert werden, sodass keine zusätzliche Konfigurationsdatei erforderlich ist. Darüber hinaus werden diese sowohl von den Turtle-Generierungsdateien als auch zum Hinzufügen von SHACL-Informationen zu Namespaces zum Dataset verwendet.

Schreiben des Ingestors

Das meiste konzentriert sich darauf, die Zeit für die Erstellung des Excel-Dokuments aufzuwenden. Sobald diese Arbeit erledigt ist, können die eigentlichen Transformationen mit zwei meiner Lieblingswerkzeuge durchgeführt werden – Vorlagenliteralen und dem auf node.js basierenden XLSX.js-Modul. Das letztere praktische Tool ist in drei Versionen erhältlich – einer einigermaßen leistungsstarken Community-Version (kostenlos und Open Source) und zwei leistungsstärkeren Unternehmensversionen, die eine bessere Formatierung von Excel-Dokumenten ermöglichen. Der hier generierte Beispielcode verwendet die Community-Version.

Ich habe eine Version eines einfachen Ingestors auf Git, die die XSLX-Datei enthält.

Dieser Ingestor ist KEIN allgemeiner Zweck – er soll nur zeigen, wie der Prozess funktioniert. Ich arbeite an einem allgemeineren Ingestor, der als Dienst ausgeführt wird, und werde Informationen dazu in den GitHub-Notizen enthalten, wenn ich fortfahre.

Die Datei index.js enthält den relevanten Javascript-Code:

Die Funktion compactToken () nimmt eine Zeichenfolge und entfernt Interpunktion und generiert eine kompakte (kein Leerzeichen) camelCase-Version der Zeichenfolge. Es wird hauptsächlich zum Generieren der URIs verwendet.

Das Objekt xlsx unterstützt das Laden in ein Excel-Dokument und das interne Konvertieren in eine Reihe von Javascript-Objekten. Das Basisobjekt ist eine Darstellung der vollständigen Arbeitsmappe, während das Array workbook.Sheets [] zum Abrufen der benannten Blätter verwendet werden kann.

Nach diesem Abschnitt werden Versionen desselben Codes effektiv wiederholt. Im ersten Abschnitt wird das Arbeitsblatt “ Namespaces ” aus dem Array abgerufen und mithilfe einer Dienstprogrammfunktion in ein Array von Objekten konvertiert, wobei die Namen in der ersten Zeile als Eigenschaftsnamen für jedes Objekt verwendet werden (d. H. ,

Anschließend wird ein Vorlagenliteral für die Behandlung jeder Zeile erstellt:

Nach der Erstellung durchläuft die Anwendung das Array und ordnet jeden Knoten (jede Zeile) einer Turtle-Präfixdeklaration zu:

Der zweite Abschnitt führt etwas Ähnliches aus, außer dass anstelle der Generierung der Schildkrötenpräfixdeklarationen SHACL-Deklarationen für dieselben Ressourcen erstellt werden:

Der folgende Abschnitt generiert die Vokabulardeklarationen, gefolgt von den Begriffsdefinitionen:

Der letzte Abschnitt generiert den NPC, der leicht das komplexeste Objekt ist. Das Javascript behandelt sowohl die Zuordnung zu den Assoziationen (Verbindung zu den URIs, die zuerst in den vorherigen Abschnitten definiert wurden), erstellt dann die Assoziationen und behandelt schließlich die Währungen:

Beachten Sie, dass Sie mit Fragment-IDs auch vordefinierte Listen (z. B. die Attributliste) durchlaufen können, um nicht nur Subjekte und Objekte, sondern auch Prädikate wie npc: hasStrength zu generieren. Dadurch wird die Ausgabe erstellt:

In diesem Beispiel wird dies im Konsolenprotokoll ausgegeben. Geben Sie Folgendes ein, um es in einer Konsole auszuführen:

oder, wenn Sie die Ausgabe beibehalten möchten, um sie in einem Textprozessor anzuzeigen, führen Sie sie wie folgt aus:

Zusammenfassung

Dies soll grundlegende Konzepte veranschaulichen, z. B. die Verwendung von Vorlagenliteralen und die Bedeutung des Entwurfs Ihres Excel unter Berücksichtigung eines bestimmten Formats / Ziels. Ich arbeite an einer allgemeineren Version davon, die in parametrisierter Form oder als Service ausgeführt werden kann und die ziemlich selbstverständliche Heuristiken verwendet, um sowohl grundlegende Anwendungsfälle zu verwalten (eine gerade Karte ohne Änderungen zu erstellen) als auch zu überschreiben bestimmte Funktionalität mit Hilfsmodulen. Darüber hinaus beabsichtige ich, den Bereich im Laufe der Zeit auf die meisten RDF-Formate zu erweitern, obwohl Turtle die höchste Priorität haben wird.

Kurt Cagle ist Schriftsteller, Informationsarchitekt und General Neer. Er lebt in Issaquah, Washington, und sieht zu, wie der Regen von seiner Katze begleitet wird.