Cookies für Statistik und Werbung
Wir setzen Cookies für Statistik und Werbung ein, beides geht an Google. Wenn du ablehnst, ändert sich für dich sichtbar nichts.Zur Datenschutzseite
XML kannst du hier kostenlos und ohne Konto in NDJSON umwandeln: Datei oben ablegen, und ein, zwei Sekunden später steht das Ergebnis zum Herunterladen bereit. Die Umwandlung läuft in deinem eigenen Browser, die Datei wird also nie hochgeladen — das klappt unter Windows, macOS und Linux ebenso wie auf iPhone und Android, und es funktioniert selbst dann noch, wenn du das Netz abschaltest.
Bis zu 100 Dateien auf einmal. Gemischte Formate sind kein Problem.
Sie werden nacheinander umgewandelt und kommen zusammen als ZIP zurück.
XML in NDJSON
Seit die öffentliche Hand in Deutschland elektronische Rechnungen im Standard XRechnung verlangt, sammeln viele Unternehmen und Behörden diese XML-Belege in großer Zahl an und wollen sie in ein Log-System, eine Analyseplattform oder einen Data-Lake laden, der zeilenweises JSON erwartet. Jede Rechnung ist ein einzelnes XML-Dokument, jede soll ein Datensatz in der Ladepipeline werden.
Genau dafür ist NDJSON gemacht — solange die Erwartung stimmt. Diese Seite schreibt jede XML-Datei als eine kompakte JSON-Zeile, und bei einer einzelnen Rechnung pro Datei ist das exakt richtig. Bei einer Sammeldatei mit mehreren Rechnungen in einem Dokument dagegen nicht, und dieser Unterschied steht hier bewusst am Anfang statt als Fußnote am Ende.
Zeilenweises JSON braucht etwas, an dem es trennen kann, und diese Trennstelle ist eine Liste ganz außen in den geparsten Daten. Das Einlesen von XML erzeugt niemals eine solche Liste: Das Ergebnis ist stets ein Objekt mit genau einem Schlüssel, dem Namen des Wurzelelements, das alles Weitere enthält. Ein Wert hinein, eine Zeile heraus.
Das gilt unabhängig von der Dateigröße und der Zahl der wiederholten Elemente darin. Eine 40 MB große Sammlung mit zehntausend Rechnungspositionen wird zu einer einzigen 40 MB langen Zeile. Verloren geht dabei nichts und aufgeteilt wird auch nichts — sollten es aber zehntausend Zeilen werden, hat diese Umwandlung die Aufgabe nicht erledigt.
Der funktionierende Weg führt über zwei Schritte. Erst die Datei nach JSON umwandeln, danach mit jq weiterverarbeiten: den Pfad zum wiederholten Element auswählen, darüber iterieren und mit der kompakten Ausgabe jedes Objekt in eine eigene Zeile schreiben. Das ist ein einziger Befehl, wiederholbar in einem Skript, und legt die Entscheidung, was als Datensatz zählt, dorthin, wo sie hingehört — zur Person, die die Pipeline baut.
Kein Konverter kann diese Wahl allein aus dem Dokument ableiten. In einer Rechnungssammlung ist der Datensatz vielleicht das Invoice-Element, in einer Behördenschnittstelle nach XÖV-Standard möglicherweise ein Feld drei Ebenen tiefer im Nachrichtenkörper, in einem Bankexport das, was der jeweilige Anbieter als Buchung bezeichnet. Ein Werkzeug, das hier rät, läge oft genug richtig, um vertraut zu werden, und gelegentlich falsch genug, um eine ganze Ladung zu verfälschen.
Dieses Paar ist keineswegs nutzlos. Liegen die Eingaben als viele kleine XML-Dateien statt als eine große vor — ein Ordner mit Einzelrechnungen, ein Verzeichnis mit Lieferscheinen, ein Stapel einzelner Meldungen —, dann ist eine Zeile je Datei exakt die Form, die eine Ladepipeline erwartet, und das Aneinanderreihen der Ausgaben ergibt einen gültigen NDJSON-Strom mit einem Datensatz je Quelldatei.
Das funktioniert auch für eine Bestandsaufnahme: Jede Konfigurationsdatei in einem Repository umwandeln und die Zeilen anhängen ergibt einen abfragbaren Datensatz darüber, was diese Dateien enthalten — durchaus nützlich und auf anderem Weg nur mit deutlich mehr Aufwand zu erreichen. In beiden Fällen leistet die Umwandlung genau das, wofür sie gedacht ist, und die einzelne Zeile ist kein Mangel, sondern das Ergebnis.
Selbst nach dem Aufteilen der Datensätze bleibt ein XML-Verhalten bestehen. Ein wiederholtes Element wird nur dann zu einem Array, wenn es mehrfach vorkommt: Eine Rechnung mit einer einzigen Position liefert eine Zeichenkette, eine mit zwei liefert eine Liste. Innerhalb desselben Datenstroms tragen manche Zeilen das Array, andere nicht.
Ein Speichersystem, das das Schema beim Lesen ableitet, orientiert sich an den ersten Datensätzen und weist alles Abweichende zurück oder erzwingt eine Umwandlung. Die richtige Stelle für die Korrektur ist der jq-Durchgang, nicht der Loader: jedes Feld, das sich wiederholen kann, beim Schreiben jeder Zeile konsequent in ein Array zwingen, damit der Strom einheitlich ist, bevor irgendein nachgelagertes System ihn sieht.
Kompaktes JSON ohne Einrückung, Schlüssel in der Reihenfolge des Dokuments, abgeschlossen mit einem Zeilenumbruch. Attribute erscheinen als Schlüssel mit vorangestelltem @, und der Text eines Elements, das zusätzlich Attribute trägt, steht unter #text. Ein Namensraum-Präfix bleibt Teil des Schlüsselnamens, sodass etwa cbc:ID ein Schlüssel mit Doppelpunkt ist, und ein Dokument mit einer XML-Deklaration trägt einen zusätzlichen obersten Schlüssel namens ?xml.
Beides lohnt sich, vor dem Laden zu entfernen. Feldnamen mit Doppelpunkt oder Fragezeichen sind in etlichen Abfragesystemen und Tabellenschemata unzulässig oder zumindest unpraktisch, und die Deklaration beschreibt die Datei, nicht die eigentlichen Daten aus ihr.
Zahlenartig aussehende Werte werden interpretiert, in Attributen wie im Elementtext gleichermaßen. Praktisch bei einer Zählgröße, problematisch bei Kennungen: Eine Rechnungsreferenz, die 007 geschrieben ist, kommt als Zahl 7 an, ein Versionsattribut mit dem Wert 1.0 als 1. In einer Datenbank werden daraus numerische Spalten, und die führenden Nullen jeder Zeile sind weg.
Ein Fall verhält sich besser, als man befürchten könnte: Eine Ganzzahl, die zu lang für eine sichere JSON-Zahl ist, bleibt als Zeichenkette erhalten statt gerundet zu werden, sodass eine neunzehnstellige Referenznummer vollständig ankommt. Wissenschaftliche Schreibweise genießt diesen Schutz nicht — ein Wert, geschrieben als 1e3, kommt als 1000 an. Ein Fehler wird dabei nirgends ausgelöst. Enthält der Bestand Referenznummern, auf die später eine Verknüpfung erfolgt, lohnt es sich, sie im jq-Durchgang zurück in Zeichenketten zu wandeln, vor dem ersten Laden statt danach.
NDJSON lesen jq, pandas mit seiner Zeilen-Option und die üblichen Warehouse-Loader unmittelbar. Ein Bulk-Import in eine Suchdatenbank braucht vor jedem Dokument eine Aktionszeile, die sich im selben jq-Durchgang ergänzen lässt, der auch die Datensätze aufteilt.
Bei diesem Paar speziell ist die Zeilenlänge der Punkt, an den niemand von selbst denkt. Ein Leser, der eine Zeile nach der anderen verarbeitet, muss die gesamte Zeile im Speicher halten — eine Zeile mit einem kompletten Dokument ist also ein kompletter Dokumentpuffer, und jede Größenbegrenzung je Datensatz beim Ziel greift dann auf die vollständige Datei statt auf einen einzelnen Datensatz. Das ist der praktische Grund, die Datensätze vor dem Laden aufzuteilen statt danach.
Kommt der Export groß, regelmäßig und muss er jedes Mal zu einem Strom werden, ist die ehrliche Empfehlung kein Browser-Konverter mehr. Ein streamender XML-Parser liest eine Datei Element für Element, ohne den gesamten Baum im Speicher aufzubauen, und aus dieser Schleife heraus eine JSON-Zeile je Datensatz zu schreiben, ist in jeder Sprache ein kurzes Programm.
Dieser Ansatz übersteht außerdem Dateien, die größer als der Arbeitsspeicher sind, was hier nicht der Fall ist — das Einlesen baut das gesamte Dokument als JavaScript-Objekte auf, bevor überhaupt ein Byte geschrieben wird. Für eine einmalige Datei oder für die oben beschriebenen Fälle mit einer Datei je Datensatz ist der Konverter schneller als das eigene Programm. Für eine wiederkehrende Pipeline ist er es nicht.
XML-Kommentare fallen beim Einlesen weg, und NDJSON kennt ohnehin keine Kommentarsyntax, um sie aufzunehmen — jede Dokumentation innerhalb des Exports ist damit verloren. Es gibt außerdem keinen Kopfbereich, kein Schema und keine Präambel: Jede Zeile einer NDJSON-Datei ist ein Datensatz, und ein Loader wird alles, was oben in der Datei steht, ebenfalls als Datensatz zu lesen versuchen.
Muss festgehalten werden, woher die Daten stammen, gehört das in ein Feld des Datensatzes oder in den Dateinamen. Eine zusätzliche erste Zeile mit dieser Information macht die Datei für ihren Zweck ungültig, und der Loader wird das deutlich weniger verständlich mitteilen, als dieser Absatz es hier tut.
| XML | NDJSON | |
|---|---|---|
| Vollständiger Name | Extensible Markup Language | Newline-Delimited JSON |
| Dateiendung | .xml | .ndjson, .jsonl |
| Medientyp | application/xml | application/x-ndjson |
| Erstmals veröffentlicht | 1998 | 2013 |
| Herausgegeben von | W3C | — |
| Spezifikation | XML 1.0 | — |
| Lizenzlage | Offener Standard | Offener Standard |
| Heutiger Stand | Aktuell | Aktuell |
| Öffnet im Browser | Jeder Browser | Kein Browser |
| Stattdessen erwogen | JSON, YAML | JSON, CSV |
Kommentare überleben nicht. In XML kannst du eine Datei kommentieren, NDJSON hat dafür keine Syntax — jede erklärende Zeile fällt weg. Das trifft genau die Dateien, die überhaupt kommentiert werden: Konfiguration, die jemand anders weiterpflegen muss.
Kein Browser liest NDJSON. Damit ist es das unhandlichere der beiden. Prüfe lieber vorher, ob die Gegenstelle es annimmt.
Die üblichen Programme überschneiden sich nicht: XML öffnest du in Visual Studio Code und oXygen XML Editor, NDJSON in jq und pandas — wer das Ergebnis bekommt, braucht also eines aus der zweiten Reihe.
XML stammt von W3C und wurde 1998 veröffentlicht. Festgehalten ist das in XML 1.0 — lohnt sich zu kennen, wenn die Datei das Programm überleben soll, das sie geschrieben hat.
NDJSON stammt aus 2013. jq und pandas lesen das Format.
XML wurde 1998 veröffentlicht, NDJSON 2013. Das ältere ist in der Regel die sicherere Datei zum Weitergeben, das jüngere erledigt dieselbe Aufgabe mit weniger Bytes.
Nein. Diese Umwandlung läuft vollständig in deinem Browser, die Datei verlässt dein Gerät also nicht. Du kannst das selbst nachprüfen: Öffne den Netzwerk-Tab der Entwicklerwerkzeuge und wandle etwas um. Zu sehen sind die Seite selbst und die Statistik- und Werbeanfragen, mit denen dieser Dienst bezahlt wird — und keine einzige, die deine Datei trägt.
Ja. Kein Konto, kein Wasserzeichen und kein Tageskontingent, das sich verbraucht — es läuft auf deinem eigenen Rechner, du darfst also so oft wiederkommen, wie du willst. Dateien bis 100 MB verarbeitet der Browser, 100 auf einmal.
XML und NDJSON beschreiben Inhalte auf grundverschiedene Weise. Die Umwandlung ist deshalb ein Nachbau und keine Kopie: originalgetreu, aber nicht Byte für Byte dasselbe. XML-Attribute und Textknoten werden beide zu Schlüsseln — eine Ermessensfrage, die der Konverter für dich entscheidet.
Kein Browser liest NDJSON. Damit ist es das unhandlichere der beiden. Prüfe lieber vorher, ob die Gegenstelle es annimmt.
Kommentare überleben nicht. In XML kannst du eine Datei kommentieren, NDJSON hat dafür keine Syntax — jede erklärende Zeile fällt weg. Das trifft genau die Dateien, die überhaupt kommentiert werden: Konfiguration, die jemand anders weiterpflegen muss.