5. Semistrukturierte Daten und Dokumentenformate
Strukturierte und semistrukturierte Daten
Abschnitt betitelt „Strukturierte und semistrukturierte Daten“Relationale Datenbanken speichern strukturierte Daten: feste Tabellen mit festen Spalten und Datentypen. Für den Austausch zwischen Systemen und für flexible Inhalte sind aber Formate verbreitet, die zwar eine Struktur haben, sich aber nicht in ein starres Tabellenschema zwängen lassen. Man nennt sie semistrukturiert. Die beiden wichtigsten sind XML und JSON.
Dieses Kapitel schaut sich beide Formate genauer an: wie sie aufgebaut sind, wie man ihre Korrektheit prüft, wie man sie gezielt abfragt und wie moderne Datenbanken sie direkt speichern.
Die drei Grade der Strukturierung
Abschnitt betitelt „Die drei Grade der Strukturierung“Daten lassen sich danach einteilen, wie stark ihre Struktur vorgegeben ist:
| Grad | Struktur | Wo steckt sie? | Beispiel |
|---|---|---|---|
| Strukturiert | starr, für alle Datensätze gleich | im Schema (getrennt von den Daten) | Tabelle customers mit id, name, zip |
| Semistrukturiert | vorhanden, aber flexibel | im Dokument selbst (Tags, Schlüssel) | JSON- oder XML-Dokument |
| Unstrukturiert | kein festes Muster | gar nicht | Foto, Video, Fließtext |
Der entscheidende Unterschied liegt darin, wo die Struktur beschrieben ist. Bei einer relationalen Tabelle steht das Schema getrennt in der Datenbank; jede Zeile muss sich daran halten. Bei semistrukturierten Daten trägt jedes Dokument seine Struktur selbst mit sich: Ein Kunde hat eine Telefonnummer, der nächste drei, ein dritter keine — und trotzdem ist jedes Dokument für sich lesbar.
Semistrukturierte Formate sind der übliche Weg, Daten zwischen Programmen und über Netzwerke auszutauschen, weil sie für Mensch und Maschine lesbar sind. Jede Web-API, jede Konfigurationsdatei, jeder Datenexport nutzt heute eines dieser Formate.
JSON (JavaScript Object Notation) ist heute das verbreitetste Austauschformat, besonders in Web-APIs. Es entstand aus der Objektschreibweise von JavaScript, ist aber sprachunabhängig: Praktisch jede Programmiersprache kann JSON lesen und schreiben.
Aufbau und Datentypen
Abschnitt betitelt „Aufbau und Datentypen“JSON kennt genau sechs Wertarten — mehr nicht, und darin liegt seine Einfachheit:
{ "customerId": 42, "name": "Andrea Hofer", "active": true, "discount": null, "phone": ["0463 123456", "0664 987654"], "address": { "zip": "9500", "city": "Villach" }}| Typ | Schreibweise | Beispiel |
|---|---|---|
| Objekt | { } mit Schlüssel-Wert-Paaren | { "zip": "9500" } |
| Array | [ ] mit geordneter Liste | ["a", "b", "c"] |
| String | in doppelten Anführungszeichen | "Villach" |
| Number | Ganz- oder Kommazahl | 42, 3.14, -1e6 |
| Boolean | Wahrheitswert | true, false |
| Null | „kein Wert” | null |
Auffällig gegenüber einer Tabelle: Werte können verschachtelt sein (die Adresse ist ein Objekt im Objekt) und mehrfach vorkommen (mehrere Telefonnummern in einem Array). Genau das lässt sich relational nur über mehrere Tabellen abbilden.
Syntaxregeln, die oft stolpern lassen
Abschnitt betitelt „Syntaxregeln, die oft stolpern lassen“JSON ist streng. Wenige Regeln, aber sie werden konsequent durchgesetzt:
- Schlüssel und Strings müssen in doppelten Anführungszeichen stehen — einfache (
'…') sind nicht erlaubt. - Kein Komma nach dem letzten Element eines Objekts oder Arrays (kein trailing comma).
- Keine Kommentare — JSON kennt sie nicht (anders als JavaScript).
- Zahlen ohne führende Null und ohne
+; der Dezimaltrenner ist immer der Punkt.
// FALSCH – so sieht ein häufiger Fehler aus:{ 'name': "Andrea", // einfache Anführungszeichen "tags": ["a", "b",], // trailing comma}JSON in der Programmiersprache
Abschnitt betitelt „JSON in der Programmiersprache“In JavaScript ist JSON direkt eingebaut. Zwei Funktionen genügen für den Weg hin und zurück:
// String -> Objekt (parsen / deserialisieren)const data = JSON.parse('{ "name": "Andrea", "active": true }');console.log(data.name); // "Andrea"
// Objekt -> String (serialisieren)const text = JSON.stringify(data, null, 2); // 2 = Einrückung für LesbarkeitDas Umwandeln eines Objekts in einen String heißt Serialisierung, der umgekehrte Weg Deserialisierung (oder Parsen). Über das Netzwerk werden immer Strings übertragen; die Struktur entsteht erst beim Parsen wieder.
XML (Extensible Markup Language) ist älter, ausführlicher und stark im Unternehmens- und Dokumentenumfeld verankert. Dieselben Daten wie oben:
<?xml version="1.0" encoding="UTF-8"?><customer id="42" active="true"> <name>Andrea Hofer</name> <phone>0463 123456</phone> <phone>0664 987654</phone> <address> <zip>9500</zip> <city>Villach</city> </address></customer>Elemente, Attribute und der Prolog
Abschnitt betitelt „Elemente, Attribute und der Prolog“XML unterscheidet zwischen Elementen und Attributen:
- Ein Element ist alles zwischen einem Start-Tag und einem End-Tag:
<name>Andrea Hofer</name>. Elemente können Text oder weitere Elemente enthalten (Verschachtelung). - Ein Attribut steht im Start-Tag und beschreibt das Element näher:
id="42". Attributwerte stehen immer in Anführungszeichen. - Ein leeres Element kann man kurz schreiben:
<phone/>statt<phone></phone>. - Die erste Zeile ist der Prolog (
<?xml … ?>). Er nennt die XML-Version und die Zeichenkodierung.
Es gibt genau ein Wurzelelement, das alles andere umschließt (hier <customer>). Fehlt es oder gibt es mehrere, ist das Dokument kaputt.
Element oder Attribut?
Abschnitt betitelt „Element oder Attribut?“Eine wiederkehrende Frage beim Entwurf: Gehört eine Angabe in ein Element oder in ein Attribut? Eine bewährte Faustregel:
- Attribute für Metadaten, die das Element beschreiben (eine ID, ein Zustand, eine Einheit).
- Elemente für die eigentlichen Daten, besonders wenn sie selbst Struktur haben oder mehrfach vorkommen können.
Ein Attribut kann pro Element nur einmal vorkommen und keine Kindstruktur tragen — deshalb wurden die Telefonnummern oben als wiederholte Elemente modelliert, nicht als Attribut.
Weitere Bausteine
Abschnitt betitelt „Weitere Bausteine“XML hat einige Sonderfälle, die man kennen sollte:
<!-- Ein Kommentar. Anders als JSON kennt XML Kommentare. --><note priority="high"> <text>5 < 10 und Tom & Jerry</text> <script><![CDATA[ if (a < b && b > c) { … } ]]></script></note>- Entitäten ersetzen Sonderzeichen, die sonst als Markup gälten:
<für<,>für>,&für&,"für",'für'. - Ein CDATA-Abschnitt (
<![CDATA[ … ]]>) schützt einen Textblock komplett vor der Interpretation — praktisch für eingebetteten Code, der viele Sonderzeichen enthält.
Namensräume
Abschnitt betitelt „Namensräume“Werden XML-Dokumente aus verschiedenen Quellen zusammengeführt, können Elementnamen kollidieren (zweimal <title> mit anderer Bedeutung). Namensräume (namespaces) lösen das über ein Präfix, das an eine eindeutige URI gebunden ist:
<root xmlns:book="https://example.org/book" xmlns:html="http://www.w3.org/1999/xhtml"> <book:title>Datenbanken</book:title> <html:title>Seitentitel</html:title></root>XML ist damit ausdrucksstärker als JSON, aber auch geschwätziger: Dieselbe Information braucht spürbar mehr Zeichen.
Wohlgeformt und valide
Abschnitt betitelt „Wohlgeformt und valide“Bei XML unterscheidet man zwei Stufen von Korrektheit:
-
Wohlgeformt (well-formed): Die reine Syntax stimmt — genau ein Wurzelelement, alle Tags korrekt verschachtelt und geschlossen, Attributwerte in Anführungszeichen, Sonderzeichen als Entitäten. Ein Parser kann das Dokument überhaupt einlesen.
-
Valide (valid): Zusätzlich hält sich das Dokument an ein Schema, das vorschreibt, welche Elemente in welcher Reihenfolge und mit welchen Typen erlaubt sind.
Ein Dokument kann wohlgeformt sein, ohne valide zu sein (die Syntax stimmt, aber es steht ein unerlaubtes Element drin). Umgekehrt geht nicht: Valide setzt Wohlgeformtheit voraus.
Schemasprachen im Vergleich
Abschnitt betitelt „Schemasprachen im Vergleich“| Sprache | Format | Für | Ausdruckskraft |
|---|---|---|---|
| DTD | eigene Syntax | XML | einfach, keine Datentypen |
| XSD (XML Schema) | selbst XML | XML | mächtig, mit Typen und Einschränkungen |
| JSON Schema | selbst JSON | JSON | mächtig, mit Typen und Einschränkungen |
Ein XSD legt für XML zum Beispiel fest, dass <zip> genau vier Ziffern hat und <customer> ein Pflicht-Attribut id braucht. Bemerkenswert dabei: Ein XSD ist selbst wieder XML — die Regeln stehen also im selben Format wie die Daten, die sie beschreiben.
Für JSON gibt es das direkte Gegenstück, JSON Schema. Auch hier gilt dasselbe Prinzip: Das Schema ist selbst wieder ein JSON-Dokument. Das folgende Beispiel beschreibt nicht einen konkreten Kunden, sondern die Regeln, denen jedes Kundenobjekt genügen muss — welche Felder Pflicht sind (required), welchen Typ sie haben und welche Einschränkungen gelten:
{ "type": "object", "required": ["customerId", "name"], "properties": { "customerId": { "type": "integer" }, "name": { "type": "string", "minLength": 1 }, "active": { "type": "boolean" }, "phone": { "type": "array", "items": { "type": "string" } } }}Damit lässt sich vor der Weiterverarbeitung sicherstellen, dass ein empfangenes Dokument die erwartete Struktur hat — ein Kunde ohne name wird zurückgewiesen, bevor er Schaden anrichtet. In Web-APIs übernimmt oft ein Validierungswerkzeug (etwa Ajv in JavaScript) diese Prüfung automatisch.
Abfragen und Verarbeiten
Abschnitt betitelt „Abfragen und Verarbeiten“Beide Formate lassen sich gezielt abfragen, ohne alles einzulesen.
Als durchgehendes Beispiel für die nächsten Abschnitte dient ein kleiner Buchladen — einmal als XML, einmal als JSON. So lassen sich dieselben Fragen in beiden Welten stellen.
<?xml version="1.0" encoding="UTF-8"?><bookstore> <book category="db" lang="de"> <title>Datenbanken</title> <author>Anna Berg</author> <author>Tom Klein</author> <year>2021</year> <price>39.90</price> </book> <book category="web" lang="en"> <title>Learning Astro</title> <author>Sara Vogt</author> <year>2024</year> <price>29.50</price> </book> <book category="db" lang="en"> <title>NoSQL Distilled</title> <author>Mike Ford</author> <year>2019</year> <price>24.00</price> </book></bookstore>{ "bookstore": { "book": [ { "category": "db", "lang": "de", "title": "Datenbanken", "authors": ["Anna Berg", "Tom Klein"], "year": 2021, "price": 39.90 }, { "category": "web", "lang": "en", "title": "Learning Astro", "authors": ["Sara Vogt"], "year": 2024, "price": 29.50 }, { "category": "db", "lang": "en", "title": "NoSQL Distilled", "authors": ["Mike Ford"], "year": 2019, "price": 24.00 } ] }}XPath für XML
Abschnitt betitelt „XPath für XML“XPath (XML Path Language) beschreibt einen Pfad durch die Baumstruktur eines XML-Dokuments, ganz ähnlich wie ein Pfad durch Verzeichnisse. Das Ergebnis einer XPath-Abfrage ist immer eine Menge von Knoten (Elemente, Attribute, Textinhalte) oder ein einfacher Wert (Zahl, Text, Wahrheitswert).
Der Weg durch den Baum
Abschnitt betitelt „Der Weg durch den Baum“XPath sieht das Dokument als Baum aus Knoten: das Dokument selbst, Elemente, Attribute und Textknoten. Ein Pfad wird aus Schritten aufgebaut, getrennt durch /:
/bookstore/book/title -> alle <title> unterhalb von /bookstore/book (absoluter Pfad)book/title -> relativ zum aktuellen Knoten/bookstore/book[1]/title -> nur der Titel des ersten Buchs| Ausdruck | Bedeutung |
|---|---|
/ | Wurzel — ein Schritt vom Dokumentanfang aus |
// | beliebig tief — überspringt Zwischenebenen |
. | der aktuelle Knoten |
.. | der Elternknoten (eine Ebene höher) |
@ | ein Attribut statt eines Elements |
* | ein beliebiges Element (Platzhalter) |
@* | ein beliebiges Attribut |
text() | der Textinhalt eines Elements |
//title -> alle <title> im ganzen Dokument, egal wie tief//book/@category -> das category-Attribut jedes Buchs//book/* -> alle Kindelemente jedes Buchs//title/text() -> die reinen Textinhalte der TitelPrädikate: filtern mit [ ]
Abschnitt betitelt „Prädikate: filtern mit [ ]“In eckigen Klammern steht eine Bedingung (ein Prädikat). Nur Knoten, die sie erfüllen, bleiben übrig. Das ist das Herzstück von XPath:
//book[@category='db'] -> alle Bücher der Kategorie db//book[price > 30] -> alle Bücher teurer als 30//book[year < 2020] -> alle vor 2020 erschienenen Bücher//book[author='Anna Berg'] -> Bücher mit diesem Autor//book[@lang='en' and price < 25] -> Englisch UND billiger als 25//book[2] -> das zweite Buch (Position!)//book[last()] -> das letzte Buch//book[price][@lang='de'] -> hat einen Preis UND ist DeutschZahlen in Klammern sind Positionen ([1] ist das erste, [last()] das letzte). XPath zählt ab 1, nicht ab 0.
Funktionen
Abschnitt betitelt „Funktionen“XPath bringt eine kleine Bibliothek von Funktionen mit, die in Prädikaten oder als Ergebnis nützlich sind:
count(//book) -> Anzahl der Bücher (hier 3)sum(//book/price) -> Summe aller Preise//book[contains(title,'Astro')] -> Titel enthält "Astro"//book[starts-with(@category,'d')]-> Kategorie beginnt mit "d"//author[position()=1] -> jeweils der erste Autorstring-length(//title[1]) -> Länge des ersten TitelsHäufig gebraucht: count(), sum(), contains(), starts-with(), not(), position(), last(), normalize-space() (entfernt überflüssige Leerzeichen).
Achsen: in jede Richtung navigieren
Abschnitt betitelt „Achsen: in jede Richtung navigieren“Bisher ging es immer nach unten (zu Kindern) oder zu Attributen. XPath kann aber in jede Richtung durch den Baum gehen — das leisten die Achsen. Die volle Schreibweise lautet achse::knotentest[prädikat]:
child::title -> Kindelemente <title> (Standard, meist weggelassen)descendant::author -> alle Nachfahren <author>, beliebig tiefparent::* -> der Elternknoten (Kurzform: ..)ancestor::book -> das umschließende <book>following-sibling::author -> nachfolgende Geschwister <author>attribute::category -> das Attribut category (Kurzform: @category)Die Kurzschreibweisen (//, .., @) sind nur bequeme Abkürzungen für die häufigsten Achsen. Für alles andere greift man zur vollen Form.
XSLT: XML umformen
Abschnitt betitelt „XSLT: XML umformen“XSLT (Extensible Stylesheet Language Transformations) ist eine eigene Sprache, um ein XML-Dokument in ein anderes Format umzuwandeln — typischerweise in HTML für die Anzeige, aber auch in reines Text-, CSV- oder anderes XML. Ein XSLT-Stylesheet ist selbst wieder XML.
Das Grundprinzip: Ein Stylesheet besteht aus Templates. Jedes Template matcht bestimmte Knoten (per XPath) und beschreibt, was für sie ausgegeben wird. Der Prozessor läuft den Baum ab und wendet auf jeden Knoten das passende Template an.
<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- Entry point: matches the document root --> <xsl:template match="/"> <html> <body> <h1>Buchliste</h1> <table> <tr><th>Titel</th><th>Jahr</th><th>Preis</th></tr> <!-- Loop over all books, sorted by price --> <xsl:for-each select="bookstore/book"> <xsl:sort select="price" data-type="number"/> <tr> <td><xsl:value-of select="title"/></td> <td><xsl:value-of select="year"/></td> <td><xsl:value-of select="price"/> €</td> </tr> </xsl:for-each> </table> </body> </html> </xsl:template>
</xsl:stylesheet>Die wichtigsten XSLT-Bausteine:
| Element | Aufgabe |
|---|---|
<xsl:template match="…"> | Regel für bestimmte Knoten (XPath) |
<xsl:value-of select="…"> | den Wert eines Knotens ausgeben |
<xsl:for-each select="…"> | über eine Knotenmenge schleifen |
<xsl:sort select="…"> | die Schleife sortieren |
<xsl:if test="…"> | bedingte Ausgabe |
<xsl:choose> / <xsl:when> | mehrere Fälle (wie switch) |
<xsl:apply-templates/> | passende Templates auf die Kinder anwenden |
Mit <xsl:if> und <xsl:choose> lässt sich die Ausgabe steuern — etwa nur teure Bücher hervorheben:
<xsl:for-each select="bookstore/book"> <xsl:if test="price > 30"> <li class="teuer"><xsl:value-of select="title"/></li> </xsl:if></xsl:for-each>JSONPath für JSON
Abschnitt betitelt „JSONPath für JSON“JSONPath ist die Idee von XPath, übertragen auf JSON. Statt / trennt ein Punkt die Schritte, statt // gibt es .., und die Wurzel heißt $. Das Ergebnis ist wieder eine Liste von Treffern.
Grundnavigation
Abschnitt betitelt „Grundnavigation“$ -> die Wurzel (das ganze Dokument)$.bookstore.book -> das book-Array$.bookstore.book[0] -> das erste Buch (JSONPath zählt ab 0!)$.bookstore.book[0].title -> dessen Titel$.bookstore.book[-1] -> das letzte Buch| Ausdruck | Bedeutung |
|---|---|
$ | Wurzelelement |
.name oder ['name'] | ein Feld (die zweite Form erlaubt Sonderzeichen) |
[n] | das n-te Array-Element (ab 0) |
[*] | alle Elemente eines Arrays |
..name | rekursiv: name in beliebiger Tiefe |
* | beliebiges Feld / Element |
$.bookstore.book[*].title -> die Titel aller Bücher$..title -> alle "title" irgendwo im Dokument$..author -> jeder "author", egal wie tief verschachteltSlices und Filter
Abschnitt betitelt „Slices und Filter“Wie in Python lassen sich Ausschnitte eines Arrays herausschneiden, und in eckigen Klammern mit ?( … ) steht ein Filter — das Gegenstück zu XPaths Prädikat. Innerhalb des Filters bezeichnet @ das gerade geprüfte Element:
$.bookstore.book[0:2] -> die ersten zwei Bücher (Slice)$.bookstore.book[?(@.price > 30)] -> alle Bücher teurer als 30$.bookstore.book[?(@.category == 'db')] -> alle db-Bücher$.bookstore.book[?(@.year < 2020)].title -> Titel der Bücher vor 2020$.bookstore.book[?(@.lang == 'en' && @.price < 25)]Alle TitelTitel des ersten BuchsBücher teurer als 30Alle Autoren, beliebig tiefDas letzte Buch$..title$.bookstore.book[0].title$.bookstore.book[?(@.price > 30)]$..author (bzw. $..authors[*])$.bookstore.book[-1]//title/bookstore/book[1]/title//book[price > 30]//author//book[last()]Die Denkweise ist dieselbe, nur die Schreibweise unterscheidet sich — und zwei Stolpersteine: JSONPath zählt Arrays ab 0, XPath zählt Positionen ab 1; und JSONPath ist (anders als XPath) kein offizieller Standard, sodass exotische Ausdrücke je nach Bibliothek leicht abweichen können.
jq auf der Kommandozeile
Abschnitt betitelt „jq auf der Kommandozeile“Für JSON auf der Shell hat sich jq durchgesetzt — mächtiger als reines JSONPath, mit Pipes wie in Unix. Werte fließen von links nach rechts durch mehrere Stufen:
# Die Titel aller Bücherjq '.bookstore.book[].title' books.json
# Nur db-Bücher, davon Titel und Preis als neues Objektjq '.bookstore.book[] | select(.category == "db") | {title, price}' books.json
# Nach Preis sortieren und den Durchschnitt berechnenjq '[.bookstore.book[].price] | add / length' books.json.[] packt ein Array aus, select( … ) filtert, {title, price} baut ein neues Objekt, add/length rechnen. Damit lässt sich JSON auf der Kommandozeile fast wie mit SQL auswerten — ideal für schnelle Auswertungen von API-Antworten.
Semistrukturierte Daten in der relationalen Datenbank
Abschnitt betitelt „Semistrukturierte Daten in der relationalen Datenbank“Wichtig ist auch: Moderne relationale Datenbanken können semistrukturierte Daten selbst speichern und abfragen. So muss man sich nicht zwischen den Welten entscheiden.
PostgreSQL hat den Datentyp jsonb (binär gespeichertes JSON) und eigene Operatoren dafür:
-- All customers from Villach; address is stored as a jsonb columnSELECT nameFROM customersWHERE address ->> 'city' = 'Villach';
-- Reach into a nested field and index it for speedSELECT name FROM customers WHERE address -> 'geo' ->> 'zone' = 'A';CREATE INDEX idx_city ON customers ((address ->> 'city'));| Operator | Bedeutung | Ergebnis |
|---|---|---|
-> | Feld als JSON | address -> 'city' → "Villach" (JSON) |
->> | Feld als Text | address ->> 'city' → Villach (Text) |
@> | enthält | tags @> '["web"]' |
So verbindet man die Stärke der relationalen Welt (Transaktionen, Joins, Constraints) mit der Flexibilität semistrukturierter Daten. Auch für XML gibt es in vielen Datenbanken einen eigenen xml-Typ samt XPath-Unterstützung.
Ein kurzer Blick auf weitere Formate
Abschnitt betitelt „Ein kurzer Blick auf weitere Formate“XML und JSON sind die wichtigsten, aber nicht die einzigen:
- YAML — gut lesbar, ohne Klammern, mit Einrückung als Struktur. Verbreitet für Konfigurationsdateien (z. B. Docker, CI-Pipelines).
- CSV — kommagetrennte Werte, minimal und tabellarisch, aber nur für flache Daten.
- TOML — Konfigurationsformat, ein Kompromiss aus Lesbarkeit und Eindeutigkeit.
- Protocol Buffers / Avro — binäre, schemagebundene Formate für sehr großen Durchsatz zwischen Diensten.
# Dieselben Daten in YAMLcustomerId: 42name: Andrea Hoferactive: truephone: - 0463 123456 - 0664 987654Sicherheit beim Verarbeiten
Abschnitt betitelt „Sicherheit beim Verarbeiten“Wer fremde Dokumente einliest, öffnet eine Angriffsfläche. Zwei klassische Fallen:
- XXE (XML External Entity): XML kann über Entitäten externe Ressourcen nachladen. Ein bösartiges Dokument kann so Dateien vom Server auslesen. Gegenmittel: externe Entitäten im Parser abschalten.
- Unkontrolliertes Parsen: Sehr tief verschachtelte oder riesige Dokumente können den Parser überlasten. Grenzen setzen und die Größe prüfen.
Wann welches Format?
Abschnitt betitelt „Wann welches Format?“- JSON für Web-APIs, Konfigurationsdateien und die Kommunikation zwischen modernen Anwendungen. Kompakt, direkt an die meisten Programmiersprachen anschlussfähig, für Menschen gut lesbar.
- XML dort, wo etablierte Standards, strenge Schemata, Namensräume oder gemischte Text-/Markup-Inhalte es verlangen (etwa Rechnungsformate wie ebInterface/ZUGFeRD, Behördenschnittstellen, Dokumentenaustausch).
Die Wahl folgt der Anforderung, nicht der Mode — genau wie bei relational gegen NoSQL.
Zusammenfassung
Abschnitt betitelt „Zusammenfassung“- Semistrukturierte Daten tragen ihre Struktur im Dokument selbst und sind flexibler als eine feste Tabelle; sie liegen zwischen strukturiert (Tabelle) und unstrukturiert (Foto, Fließtext).
- JSON ist das kompakte Standardformat für Web-APIs mit sechs Wertarten (Objekt, Array, String, Number, Boolean, Null); die Syntax ist streng (doppelte Anführungszeichen, kein trailing comma, keine Kommentare).
- XML ist ausführlicher und unterscheidet Elemente, Attribute, Entitäten, CDATA und Namensräume; es hat genau ein Wurzelelement.
- Wohlgeformtheit betrifft die Syntax, Validität die Übereinstimmung mit einem Schema (DTD, XSD, JSON Schema).
- Abgefragt wird XML mit XPath/XSLT, JSON mit JSONPath/
jqoder direkt in der Programmiersprache; Serialisierung und Deserialisierung wandeln zwischen String und Objekt. - Relationale Datenbanken speichern semistrukturierte Daten auch selbst — PostgreSQL etwa als
jsonbmit eigenen Operatoren (->,->>,@>). - Empfangene Dokumente werden erst validiert, dann verarbeitet — auch aus Sicherheitsgründen (Stichwort XXE).