Technik 9 Min. Lesezeit

XML-Attribute, Namespaces und Arrays nach JSON mappen

XML kennt Attribute, Namespaces und gemischte Inhalte, JSON nicht. Wer XML sauber in JSON umwandeln will, muss diese Konzepte über feste Konventionen abbilden. Dieser Ratgeber zeigt die gängigen Mapping-Regeln, die Stolperfallen und wie Sie verlustfreie Ergebnisse erhalten.

Eike-Christian Ramcke
Eike-Christian Ramcke
Aktualisiert: Juni 2026

Die Umwandlung von XML nach JSON sieht auf den ersten Blick trivial aus: ein Element wird zu einem Schlüssel, sein Inhalt zum Wert. In der Praxis scheitern Konvertierungen aber regelmäßig an drei Stellen, an denen die beiden Formate grundlegend verschieden ticken: bei Attributen, bei wiederholten Elementen und bei Namespaces. Da das JSON-Datenmodell (definiert in ECMA-404 und RFC 8259) keines dieser drei Konzepte nativ kennt, muss jeder Konverter sie über Konventionen nachbilden. Welche Konvention er wählt, entscheidet darüber, ob Ihr JSON verlustfrei, stabil und maschinell weiterverarbeitbar ist.

1. Warum XML und JSON nicht deckungsgleich sind

XML ist eine Auszeichnungssprache mit einem reichhaltigen Datenmodell. Ein Element kann gleichzeitig Attribute, Kindelemente und Textinhalt tragen, es gibt Namespaces zur Disambiguierung von Bezeichnern, geordnete Geschwister, Kommentare, Processing Instructions und CDATA-Abschnitte. JSON dagegen kennt nur sechs Bausteine: Objekt, Array, String, Zahl, Boolean und null. Es gibt keine Attribute, keine geordnete Sortierung benannter Eigenschaften und kein Namespace-System.

Eine verlustfreie Abbildung von XML nach JSON ist deshalb nur möglich, wenn man die fehlenden Konzepte über Namenskonventionen in das JSON-Objektmodell kodiert. Genau das tun alle ernstzunehmenden Konverter. Die folgende Grafik zeigt, welches XML-Konstrukt auf welches JSON-Konstrukt abgebildet wird.

Mapping von XML-Konstrukten nach JSON Element wird zu Schlüssel, Attribut zu @-Eigenschaft, wiederholtes Element zu Array, Textinhalt zu #text. XML JSON <buch>...</buch> "buch": { ... } jahr="2024" "@jahr": "2024" Textinhalt "#text": "..." <tag> (2x gleich) <tag> ... "tag": [ ..., ... ] soap:Envelope "soap:Envelope"
Grundprinzip: XML-Konstrukte werden über feste Namenskonventionen in das JSON-Objektmodell kodiert.

2. Attribute mit @-Präfix und #text abbilden

Attribute sind der erste Knackpunkt. In XML hängen sie direkt am Element-Tag und unterscheiden sich syntaktisch klar von Kindelementen. In JSON gibt es diese Unterscheidung nicht: alles wird zu einer Eigenschaft im selben Objekt. Damit Attribute nicht versehentlich mit gleichnamigen Kindelementen kollidieren, bekommen sie ein reserviertes Präfix. Das mit Abstand verbreitetste Präfix ist das At-Zeichen (@), wie es unter anderem die JavaScript-Bibliothek fast-xml-parser und die Badgerfish-Konvention verwenden.

Hat ein Element zugleich Attribute und Textinhalt (in XML "mixed content" genannt), braucht der Text einen eigenen Platz. Dafür gibt es eine zweite reservierte Eigenschaft, meist #text oder $. Ein konkretes Beispiel:

<!-- XML -->
<artikel id="A-42" verfuegbar="true">
  <name>USB-C Kabel</name>
  <preis waehrung="EUR">19.90</preis>
</artikel>
// JSON (Konvention: @-Präfix, #text)
{
  "artikel": {
    "@id": "A-42",
    "@verfuegbar": "true",
    "name": "USB-C Kabel",
    "preis": {
      "@waehrung": "EUR",
      "#text": "19.90"
    }
  }
}

Beachten Sie: Das Element name hat keine Attribute und keinen gemischten Inhalt, deshalb wird sein Text direkt als String geschrieben, nicht als #text-Objekt. Das Element preis hat ein Attribut und Text, deshalb entsteht ein Objekt mit beiden Eigenschaften. Genau dieser Unterschied macht das Ergebnis-Schema unregelmäßig und ist beim Weiterverarbeiten zu berücksichtigen.

Stolperfalle: Präfix-Kollision

Enthält Ihr XML ein Attribut und ein Kindelement mit demselben Namen, etwa ein Attribut typ und ein Element <typ>, verhindert das @-Präfix die Kollision. Ohne Präfix würde eine der beiden Angaben überschrieben und damit unbemerkt verloren gehen. Schalten Sie das Attribut-Präfix daher niemals leichtfertig ab.

3. Wiederholte Elemente als Arrays

Die zweite große Hürde ist die Array-Bildung. In XML ist es völlig normal, dass dasselbe Element mehrfach unter einem Eltern-Element auftaucht: eine Bestellung mit mehreren Positionen, ein Feed mit mehreren Einträgen. JSON drückt Wiederholung über Arrays aus. Konverter erkennen wiederholte gleichnamige Geschwister und fassen sie zu einem Array zusammen:

<bestellung>
  <position>Maus</position>
  <position>Tastatur</position>
</bestellung>

// -> { "bestellung": { "position": ["Maus", "Tastatur"] } }

Das Problem: Kommt nur eine einzige Position vor, erzeugt ein naiver Konverter ein einzelnes Objekt statt eines Arrays mit einem Element. Dasselbe Quell-Schema liefert also je nach Datenmenge mal ein Array, mal ein Objekt. Code, der stur über position[0] zugreift, bricht dann beim Einzelfall.

Tipp: Arrays erzwingen

Viele Bibliotheken bieten eine Option, bestimmte Pfade immer als Array auszugeben. In fast-xml-parser heißt sie isArray, in xml2js gibt es explicitArray: true. Damit wird jedes Kindelement konsequent zu einem Array, das Schema bleibt stabil, und Ihr Code muss keine Sonderfälle für "ein Element" behandeln. Für Datenpipelines ist das fast immer die robustere Wahl.

4. Namespaces wie soap: und xsi:

XML-Namespaces (definiert vom W3C in "Namespaces in XML 1.0") trennen Bezeichner aus unterschiedlichen Vokabularen, damit ein title aus einem Atom-Feed nicht mit einem title aus XHTML kollidiert. Technisch besteht ein qualifizierter Name aus einem Präfix und dem lokalen Namen, getrennt durch einen Doppelpunkt: soap:Envelope, xsi:type. Das Präfix selbst ist nur eine Abkürzung für eine URI, die im xmlns-Attribut deklariert wird.

Da JSON kein Namespace-Konzept besitzt, übernimmt der Standardweg das vollständige qualifizierte Präfix einfach als Teil des Schlüssels. Aus <soap:Envelope> wird der Schlüssel "soap:Envelope". Das ist verlustfrei und eindeutig:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <m:GetPrice xmlns:m="https://example.com/stock">
      <m:Symbol>DE000</m:Symbol>
    </m:GetPrice>
  </soap:Body>
</soap:Envelope>

// JSON
{
  "soap:Envelope": {
    "@xmlns:soap": "http://schemas.xmlsoap.org/soap/envelope/",
    "soap:Body": {
      "m:GetPrice": {
        "@xmlns:m": "https://example.com/stock",
        "m:Symbol": "DE000"
      }
    }
  }
}

Warnung: Präfixe entfernen ist riskant

Manche Tools bieten an, Namespace-Präfixe abzustreifen, damit die Schlüssel kürzer werden. Das funktioniert nur, solange im Dokument keine zwei gleichnamigen lokalen Namen aus verschiedenen Namespaces vorkommen. Treten sie doch auf, kollidieren die Schlüssel und Daten gehen verloren. Außerdem ist das Präfix in XML frei wählbar: dasselbe Vokabular kann in einem Dokument m:, im nächsten stock: heißen. Verlassen Sie sich für die Bedeutung also nie auf das Präfix, sondern auf die deklarierte URI.

5. Badgerfish, Parker & Co. im Überblick

Es gibt keinen einzigen offiziellen Standard für die XML-zu-JSON-Abbildung, aber mehrere etablierte Konventionen mit klaren Regeln. Die wichtigsten sind Badgerfish (2007), die Parker-Konvention und die pragmatischen Defaults verbreiteter Bibliotheken. Sie unterscheiden sich vor allem darin, wie viel Information sie erhalten und wie kompakt die Ausgabe ist.

Konvention Attribut Textinhalt Verlustfrei?
Badgerfish @name $ Ja, inkl. Namespaces
Parker verworfen direkter Wert Nein, kompakt
fast-xml-parser (Default) @_name #text Ja, konfigurierbar
xml2js (Node) $.name _ Ja
xmltodict (Python) @name #text Ja

Praktischer Rat: Für reine Anzeige reicht die kompakte Parker-Variante. Sobald Sie XML jedoch nach JSON umwandeln, weiterverarbeiten und eventuell zurück nach XML wollen (Round-Trip), nehmen Sie eine verlustfreie Konvention mit @-Präfix und #text. Unser Converter folgt genau dieser verlustfreien Logik mit @-Präfix für Attribute und #text für gemischte Inhalte.

6. Datentypen und Typinferenz

XML hat im Kern keine Datentypen, jeder Inhalt ist Text. JSON dagegen unterscheidet Strings, Zahlen, Booleans und null. Ein vorsichtiger Konverter übernimmt deshalb alle Werte zunächst als String. Das wirkt umständlich, schützt aber vor stillen Datenverlusten:

Aktivieren Sie Typinferenz daher nur, wenn Sie Ihre Daten kennen. Bibliotheken nennen die Option meist parseNumbers, parseTrueNumberOnly oder numberParseOptions. Wer ein formales Schema braucht, definiert die Typen besser explizit per JSON Schema statt sie zu raten.

7. Die häufigsten Stolperfallen

  1. Reihenfolge geht verloren. JSON-Objekte garantieren keine Reihenfolge der Schlüssel. Bei gemischtem Inhalt mit Text zwischen Elementen kann die ursprüngliche Sequenz nicht ohne Weiteres rekonstruiert werden.
  2. Leere Elemente. <wert/> wird je nach Tool zu null, leerem String oder leerem Objekt. Prüfen Sie das Verhalten Ihres Konverters.
  3. Mixed Content mit Markup. Text, der Inline-Elemente umschließt (typisch in Dokumenten-XML), lässt sich kaum verlustfrei in flaches JSON pressen.
  4. Single-vs-Array-Inkonsistenz. Wie in Abschnitt 3 beschrieben die wohl häufigste Quelle für Laufzeitfehler in nachgelagertem Code.
  5. Namespace-Präfix als Bedeutungsträger missverstehen. Das Präfix ist austauschbar, nur die URI ist verbindlich.

XML jetzt verlustfrei nach JSON umwandeln

Unser Converter wendet die hier beschriebenen Konventionen automatisch an, mit @-Präfix für Attribute und #text für gemischte Inhalte. Alles läuft 100% in Ihrem Browser, ohne Upload.

Zum XML zu JSON Converter

Häufige Fragen

Wie werden XML-Attribute in JSON dargestellt?

Attribute haben in JSON keine eigene Ebene, daher werden sie als gewöhnliche Eigenschaften in das Objekt des Elements aufgenommen. Die verbreitetste Konvention ist ein @-Präfix. Aus <preis waehrung="EUR">19.90</preis> wird so { "preis": { "@waehrung": "EUR", "#text": "19.90" } }. Manche Konverter nutzen statt @ ein Unterstrich-Präfix oder einen frei wählbaren String.

Wozu dient die Eigenschaft #text in JSON?

Hat ein XML-Element gleichzeitig Attribute und Textinhalt, muss der Text irgendwo abgelegt werden, ohne mit den Attributen zu kollidieren. Dafür gibt es eine reservierte Eigenschaft, üblicherweise #text. Hat ein Element nur Text und keine Attribute, sparen die meisten Konverter das #text und schreiben den Wert direkt als String.

Wann werden wiederholte XML-Elemente zu einem Array?

Treten gleichnamige Kindelemente mehrfach unter demselben Eltern-Element auf, fasst der Konverter sie zu einem JSON-Array zusammen. Bei nur einem Vorkommen entsteht dagegen ein einzelnes Objekt, kein Array mit einem Element. Diese Mehrdeutigkeit ist die häufigste Stolperfalle, weil dasselbe Schema je nach Datenmenge mal ein Objekt, mal ein Array liefert.

Wie werden XML-Namespaces wie soap: oder xsi: in JSON behandelt?

JSON kennt kein Namespace-Konzept. Standardmäßig wird das qualifizierte Präfix daher als reiner Bestandteil des Schlüssels übernommen, etwa "soap:Envelope" oder "xsi:type". Das Mapping bleibt damit verlustfrei und eindeutig. Wer die Präfixe entfernen will, riskiert Schlüsselkollisionen und sollte das nur tun, wenn die Quelldaten keine gleichnamigen Elemente aus verschiedenen Namespaces enthalten.

Warum sind Zahlen nach der Konvertierung oft Strings?

XML kennt keine Datentypen, jeder Wert ist dort reiner Text. Ein konservativer Konverter übernimmt Werte deshalb als String, um Datenverluste wie führende Nullen in Postleitzahlen oder ISBN-Nummern zu vermeiden. Eine optionale Typinferenz kann "42" zur Zahl 42 machen, sollte aber bewusst aktiviert werden.

Was ist die Badgerfish-Konvention?

Badgerfish ist eine standardisierte Mapping-Konvention von 2007. Sie schreibt Attribute mit @-Präfix, legt Textinhalt in $ ab und bildet Namespace-Deklarationen in einem speziellen @xmlns-Objekt ab. Die Alternative Parker-Konvention verwirft Attribute und Wurzelnamen zugunsten kompakterer, aber verlustbehafteter Ausgabe.

Quellen

Verwandte Artikel

Anzeige
Anzeige
Anzeige
Anzeige
Anzeige