<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang=""> <head> <meta charset="utf-8" /> <meta name="generator" content="pandoc" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" /> <title>specs.md</title> <style> code{white-space: pre-wrap;} span.smallcaps{font-variant: small-caps;} div.columns{display: flex; gap: min(4vw, 1.5em);} div.column{flex: auto; overflow-x: auto;} div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;} /* The extra [class] is a hack that increases specificity enough to override a similar rule in reveal.js */ ul.task-list[class]{list-style: none;} ul.task-list li input[type="checkbox"] { font-size: inherit; width: 0.8em; margin: 0 0.8em 0.2em -1.6em; vertical-align: middle; } .display.math{display: block; text-align: center; margin: 0.5rem auto;} /* CSS for syntax highlighting */ pre > code.sourceCode { white-space: pre; position: relative; } pre > code.sourceCode > span { line-height: 1.25; } pre > code.sourceCode > span:empty { height: 1.2em; } .sourceCode { overflow: visible; } code.sourceCode > span { color: inherit; text-decoration: inherit; } div.sourceCode { margin: 1em 0; } pre.sourceCode { margin: 0; } @media screen { div.sourceCode { overflow: auto; } } @media print { pre > code.sourceCode { white-space: pre-wrap; } pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; } } pre.numberSource code { counter-reset: source-line 0; } pre.numberSource code > span { position: relative; left: -4em; counter-increment: source-line; } pre.numberSource code > span > a:first-child::before { content: counter(source-line); position: relative; left: -1em; text-align: right; vertical-align: baseline; border: none; display: inline-block; -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; padding: 0 4px; width: 4em; color: #aaaaaa; } pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; } div.sourceCode { } @media screen { pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; } } code span.al { color: #ff0000; font-weight: bold; } /* Alert */ code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */ code span.at { color: #7d9029; } /* Attribute */ code span.bn { color: #40a070; } /* BaseN */ code span.bu { color: #008000; } /* BuiltIn */ code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */ code span.ch { color: #4070a0; } /* Char */ code span.cn { color: #880000; } /* Constant */ code span.co { color: #60a0b0; font-style: italic; } /* Comment */ code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */ code span.do { color: #ba2121; font-style: italic; } /* Documentation */ code span.dt { color: #902000; } /* DataType */ code span.dv { color: #40a070; } /* DecVal */ code span.er { color: #ff0000; font-weight: bold; } /* Error */ code span.ex { } /* Extension */ code span.fl { color: #40a070; } /* Float */ code span.fu { color: #06287e; } /* Function */ code span.im { color: #008000; font-weight: bold; } /* Import */ code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */ code span.kw { color: #007020; font-weight: bold; } /* Keyword */ code span.op { color: #666666; } /* Operator */ code span.ot { color: #007020; } /* Other */ code span.pp { color: #bc7a00; } /* Preprocessor */ code span.sc { color: #4070a0; } /* SpecialChar */ code span.ss { color: #bb6688; } /* SpecialString */ code span.st { color: #4070a0; } /* String */ code span.va { color: #19177c; } /* Variable */ code span.vs { color: #4070a0; } /* VerbatimString */ code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */ </style> <link rel="stylesheet" href="/home/henrik/Documents/programmierung/markdown-viewer/markdown-styles/markdown5.css" /> <!--[if lt IE 9]> <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script> <![endif]--> </head> <body> <p>Top level of json must be a dict. keys of the dict are RT names.</p> <p>Frage: is the first RT never an array?</p> <p>Do not use sheet name, but only content of hidden rows</p> <p>Das Datenmodell in LinkAhead legt fest, welche Arten von Records es in einer LinkAhead-Instanz gibt und wie diese aussehen. Diese Datenmodell kann auch in einem JSON Schema repräsentiert werden, dass die Struktur von JSON Dateien festlegt, die zu dem Datenmodell gehörige Records enthält. Zum Beispiel kann das folgende JSON den Record einer Person beschreiben:</p> <div class="sourceCode" id="cb1"><pre class="sourceCode json"><code class="sourceCode json"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span> <span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"Person"</span><span class="fu">:</span> <span class="fu">{</span></span> <span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"family_name"</span><span class="fu">:</span> <span class="st">"Steve"</span><span class="fu">,</span></span> <span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"given_name"</span><span class="fu">:</span> <span class="st">"Stevie"</span></span> <span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span> <span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div> <p>Das JSON Schema schreibt eine konkrete Struktur vor und kann zugehörige JSON Dateien können genutzt werden um Daten zu bestimmten Record Strukturen zu repräsentieren. Beispielsweise könnte man ein JSON Schema erstellen, dass es erlaubt “Training” Records mit Informationen zu abgehaltenen Trainings speichern. Dies ist insbesondere wertvoll beim Datenim- und export. Man könnte basierend auf dem im Folgenden beschriebenen Webformulare basieren oder es nutzen um in LinkAhead gespeicherte Objekte als JSON zu exportieren.</p> <p>Im Folgenden wird beschrieben, wie JSON Dateien mit solchen Records in XLSX Dateien umgewandelt werden, bzw. wie aus XLSX-Dateien JSON Dateien mit Records erstellt werden.</p> <p>Der Attributname (oben “Person”) legt den RecordType fest und der Wert diese Attributs kann entweder ein Objekt oder eine Liste sein. Ist es ein Objekt (wie im obigen Beispiel), so wird ein einzelner Record repräsentiert. Bei einer Liste mehrere Records, die den gleichen RecordType als Parent haben. Die Properties des Records (oben “family_name” und “given_name”) werden zu Spalten im XLSX. Die Properties haben wiederum einen Attributnamen und einen Wert. Der Wert kann a. primitiv (Text, Zahl, Boolean, …) b. ein Record c. eine Liste von primitiven Typen d. eine Liste von Records sein.</p> <p>In den Fällen a. und c. wird in XLSX eine Zelle in der zur Property gehörigen Spalte erstellt. Im Fall b. wird prinzipiell für die Properties des Records Spalten erstellt. Tatsächlich wird der referenzierte Record genauso behandelt wie der ursprüngliche. D.h. die Fälle a.-d. werden wieder für die einzelnen Properties betrachtet. Für den Fall d. ist die zweidimensionale Struktur eines XLSX Blatts nicht ausreichend. Daher werden für solche Fälle neue XLSX Blätter erstellt. In diesen werden die referenzierten Records behandelt wie oben beschrieben. Es gibt jedoch zusätzliche Spalten die es erlauben zu erkennen von welchem Record die Records referenziert werden.</p> <p>Wir betrachten diese vier Fälle nun im Detail: a. Properties mit primitiven Datentypen</p> <div class="sourceCode" id="cb2"><pre class="sourceCode json"><code class="sourceCode json"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span> <span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"Training"</span><span class="fu">:</span> <span class="fu">{</span></span> <span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"date"</span><span class="fu">:</span> <span class="st">"2023-01-01"</span><span class="fu">,</span></span> <span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"url"</span><span class="fu">:</span> <span class="st">"www.indiscale.com"</span><span class="fu">,</span></span> <span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"duration"</span><span class="fu">:</span> <span class="fl">1.0</span><span class="fu">,</span></span> <span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">"participants"</span><span class="fu">:</span> <span class="dv">1</span><span class="fu">,</span></span> <span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">"remote"</span><span class="fu">:</span> <span class="kw">false</span></span> <span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span> <span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div> <p>Dies würde in einem XLSX Blatt mit dem folgenden Inhalt abgebildet:</p> <table> <thead> <tr class="header"> <th>date</th> <th>url</th> <th>duration</th> <th>participants</th> <th>remote</th> <th></th> </tr> </thead> <tbody> <tr class="odd"> <td>2023-01-01</td> <td>www.indiscale.com</td> <td>1.0</td> <td>1</td> <td>false</td> <td></td> </tr> </tbody> </table> <ol start="2" type="a"> <li>Property, die einen Record referenziert</li> </ol> <div class="sourceCode" id="cb3"><pre class="sourceCode json"><code class="sourceCode json"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span> <span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"Training"</span><span class="fu">:</span> <span class="fu">{</span></span> <span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"date"</span><span class="fu">:</span> <span class="st">"2023-01-01"</span><span class="fu">,</span></span> <span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"supervisor"</span><span class="fu">:</span> <span class="fu">{</span></span> <span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">"family_name"</span><span class="fu">:</span> <span class="st">"Steve"</span><span class="fu">,</span></span> <span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">"given_name"</span><span class="fu">:</span> <span class="st">"Stevie"</span><span class="fu">,</span></span> <span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span> <span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span> <span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div> <p>Dies würde in einem XLSX Blatt mit dem folgenden Inhalt abgebildet:</p> <table> <thead> <tr class="header"> <th>date</th> <th>supervisor.family_name</th> <th>supervisor.given_name</th> </tr> </thead> <tbody> <tr class="odd"> <td>2023-01-01</td> <td>Steve</td> <td>Stevie</td> </tr> </tbody> </table> <p>Beachten Sie, dass die Spaltennamen umbenannt werden dürfen. Die Zuordnung der Spalte zu Properties von Records wird über den Inhalt von versteckten Zeilen gewährleistet.</p> <ol start="3" type="a"> <li>Properties, die Listen mit Werten von primitiven Datentypen enthalten</li> </ol> <div class="sourceCode" id="cb4"><pre class="sourceCode json"><code class="sourceCode json"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span> <span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"Training"</span><span class="fu">:</span> <span class="fu">{</span></span> <span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"url"</span><span class="fu">:</span> <span class="st">"www.indiscale.com"</span><span class="fu">,</span></span> <span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"subjects"</span><span class="fu">:</span> <span class="ot">[</span><span class="st">"Math"</span><span class="ot">,</span> <span class="st">"Physics"</span><span class="ot">]</span><span class="fu">,</span></span> <span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span> <span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div> <p>Dies würde in einem XLSX Blatt mit dem folgenden Inhalt abgebildet:</p> <table> <thead> <tr class="header"> <th>url</th> <th>subjects</th> <th></th> <th></th> <th></th> <th></th> </tr> </thead> <tbody> <tr class="odd"> <td>www.indiscale.com</td> <td>Math;Physics</td> <td></td> <td></td> <td></td> <td></td> </tr> </tbody> </table> <p>Die Listenelemente werden separiert von <code>;</code> in die Zelle geschrieben.</p> <ol start="4" type="a"> <li>Properities, die Listen mit Referenzen enthalten</li> </ol> <div class="sourceCode" id="cb5"><pre class="sourceCode json"><code class="sourceCode json"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span> <span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">"Training"</span><span class="fu">:</span> <span class="fu">{</span></span> <span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">"date"</span><span class="fu">:</span> <span class="st">"2023-01-01"</span><span class="fu">,</span></span> <span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">"coach"</span><span class="fu">:</span> <span class="ot">[</span></span> <span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a> <span class="fu">{</span></span> <span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">"family_name"</span><span class="fu">:</span> <span class="st">"Sky"</span><span class="fu">,</span></span> <span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">"given_name"</span><span class="fu">:</span> <span class="st">"Max"</span><span class="fu">,</span></span> <span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span><span class="ot">,</span><span class="fu">{</span></span> <span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">"family_name"</span><span class="fu">:</span> <span class="st">"Sky"</span><span class="fu">,</span></span> <span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a> <span class="dt">"given_name"</span><span class="fu">:</span> <span class="st">"Min"</span><span class="fu">,</span></span> <span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span><span class="ot">]</span><span class="fu">,</span></span> <span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span> <span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div> <p>Da die beiden Coaches nicht vernünftig in einer Zelle dargestellt werden können, bedarf es nun eines weiteren Tabellenblatts, das die Eigenschaften der Coaches enthält.</p> <p>Das Blatt zu den Trainings enthält in diesem Beispiel nur die “date” Spalte:</p> <table> <thead> <tr class="header"> <th>date</th> </tr> </thead> <tbody> <tr class="odd"> <td>2023-01-01</td> </tr> </tbody> </table> <p>Zusätzlich gibt es ein weiteres Blatt in dem die Coaches gespeichert werden. Hier ist nun entscheidend, dass definiert wird, wie von potentiell mehreren “Trainings” das richtige Element gewählt wird. In diesem Fall bedeutet dies, dass das “date” eindeutig sein muss TODO: In welchem Scope gilt diese Eindeutigkeit? Können wir dies checken? Das zweite Blatt sieht dann wie folgt aus</p> <table> <thead> <tr class="header"> <th>date</th> <th>coach.family_name</th> <th>coach.given_name</th> </tr> </thead> <tbody> <tr class="odd"> <td>2023-01-01</td> <td>Sky</td> <td>Max</td> </tr> <tr class="even"> <td>2023-01-01</td> <td>Sky</td> <td>Min</td> </tr> </tbody> </table> </body> </html>