← Tous les articles

Conversion XML vers JSON : attributs, nœuds texte, tableaux et namespaces

Convertir XML en JSON correctement : comment les attributs, nœuds texte, éléments répétés et namespaces se mappent en JSON — avec conventions, cas limites et code JS/Python.

Convertir XML en JSON paraît mécanique jusqu’à ce qu’on tombe sur les parties d’XML pour lesquelles JSON n’a pas d’équivalent direct : attributs, contenu mixte texte+élément, éléments apparaissant une ou plusieurs fois, et namespaces. Il n’y a pas un seul mapping « correct » —— juste des conventions. Ce guide explique les conventions standard, les décisions à prendre, et comment convertir XML en JSON en JavaScript, Python et dans le navigateur.

Le mapping en un coup d’œil

La plupart des convertisseurs XML→JSON (xmltodict, fast-xml-parser et l’outil de ce site) suivent la même forme : chaque élément devient un objet, les attributs deviennent des clés à préfixe spécial, et le texte devient soit la valeur, soit une clé réservée.

<!-- XML -->
<note id="1" priority="high">
  <to>Ada</to>
  <from>Bob</from>
  <body>Hello &amp; welcome</body>
</note>
// JSON
{
  "note": {
    "@id": "1",
    "@priority": "high",
    "to": "Ada",
    "from": "Bob",
    "body": "Hello & welcome"
  }
}

Attributs → clés préfixées par @

Les objets JSON n’ont pas la notion d’attribut, donc la convention quasi universelle est de préfixer les noms d’attributs par @. Cela les distingue des éléments enfants et rend le mapping réversible.

<book id="b1" lang="en"/>
→ { "book": { "@id": "b1", "@lang": "en" } }

Certains outils utilisent un autre préfixe ($, _) ou un objet imbriqué "@attributes". Choisissez-en un et appliquez-le de façon cohérente —— le code en aval doit savoir où sont les attributs.

Nœuds texte et contenu mixte

Quand un élément ne contient que du texte, il se réduit à une valeur chaîne. Mais quand un élément a des attributs et du texte, le texte doit aller quelque part —— par convention la clé #text.

<price currency="USD">9.99</price>
→ { "price": { "@currency": "USD", "#text": "9.99" } }

<title>Effective TypeScript</title>
→ { "title": "Effective TypeScript" }

Le contenu vraiment mixte (texte entrelacé avec des éléments enfants, comme dans un markup type HTML) est le cas le plus difficile —— la plupart des convertisseurs orientés données concatènent ou suppriment le texte libre. Si votre XML est de style document plutôt que données, attendez-vous à de la perte ici.

Le problème objet vs tableau

C’est le piège qui casse plus de code que tous les autres. Un élément apparaissant une fois devient un objet ; le même élément apparaissant deux fois devient un tableau. La forme JSON dépend donc des données, pas du schéma :

<tags><tag>a</tag></tags>
→ { "tags": { "tag": "a" } }          // objet

<tags><tag>a</tag><tag>b</tag></tags>
→ { "tags": { "tag": ["a", "b"] } }   // tableau

Les consommateurs qui attendent tags.tag toujours en tableau planteront sur le cas mono-élément. Deux corrections : configurer le parseur pour traiter les éléments répétables connus toujours comme des tableaux, ou normaliser après parsing (const arr = [].concat(node.tag ?? [])).

Namespaces

Les namespaces XML utilisent des préfixes (soap:Envelope) liés par des déclarations xmlns. JSON n’a pas la notion de namespace, donc les convertisseurs choisissent l’une de ces approches :

  • Garder le préfixe dans la clé —— "soap:Envelope". Simple et réversible, mais la clé contient un deux-points, donc accès par crochets (obj["soap:Envelope"]).
  • Retirer le préfixe —— "Envelope". Clés plus propres, mais perte du namespace et risque de collision entre deux namespaces partageant le même nom local.
  • Garder xmlns comme attributs —— les déclarations deviennent des clés "@xmlns:soap" pour que la liaison survive à l’aller-retour.

Pour la plupart des tâches de données, garder le préfixe dans la clé est le défaut le plus sûr —— il ne perd jamais d’information.

Entités et CDATA

Un convertisseur correct décode les cinq entités prédéfinies (&lt;, &gt;, &amp;, &quot;, &apos;) et les références numériques (&#169;) en leurs caractères, et traite les blocs <![CDATA[...]]> comme du texte littéral.

Conventions nommées : BadgerFish, GData, Parker

Le mapping « @ pour attributs / #text pour texte » n’est pas le seul schéma. Trois conventions nommées rencontrées en lisant des sorties XML→JSON d’autres systèmes :

  • BadgerFish —— attributs sous une clé préfixée @ ; texte sous $ ; déclarations de namespaces sous @xmlns. Verbeux mais sans perte.
  • GData —— la variante Google : attributs préfixés par $ ; texte sous $t ; éléments répétés toujours en tableau. Sans perte, forme prévisible.
  • Parker —— retire complètement les attributs ; le mapping le plus simple et le plus lossy. Utile quand vous contrôlez les deux bouts et ne vous souciez que des valeurs des éléments.

Quand vous intégrez avec un système produisant déjà du JSON-from-XML, identifiez la convention utilisée avant d’écrire le code de parsing.

Interroger le résultat avec JSONPath

Une fois le XML converti, vous pouvez adresser les valeurs avec JSONPath. Deux petits ajustements par rapport aux habitudes XPath :

  • Les clés d’attributs portent le préfixe @ du mapping, donc le @id d’XPath devient $..['@id'] en JSONPath.
  • Le problème objet vs tableau ci-dessus fait qu’un XPath qui marche comme book/title peut devoir s’écrire $..book[*].title en JSONPath pour gérer les deux formes.

Convertir XML en JSON en code

// JavaScript (navigateur) —— DOMParser + un petit walker, ou une librairie :
import { XMLParser } from 'fast-xml-parser';
const parser = new XMLParser({ ignoreAttributes: false, attributeNamePrefix: '@' });
const obj = parser.parse(xmlString);

# Python —— xmltodict mappe les attributs en "@name" et le texte en "#text"
import xmltodict, json
doc = xmltodict.parse(xml_string)
print(json.dumps(doc, indent=2))

Convertir XML en JSON en ligne

Pour une conversion rapide, collez votre XML dans le convertisseur JSON ⇄ XML et cliquez sur To JSON. Il applique les conventions ci-dessus —— @ pour les attributs, #text pour le contenu mixte, tableaux pour les éléments répétés —— et tourne intégralement dans votre navigateur, donc les flux internes et payloads d’API ne quittent jamais votre machine.

Questions fréquentes

Comment les attributs XML sont-ils représentés en JSON ?

Par convention, ils deviennent des clés préfixées par @ (par ex. @id), distinctes des éléments enfants pour que le mapping puisse s’inverser.

Pourquoi le même élément devient-il parfois objet, parfois tableau ?

Parce que la forme suit les données : une occurrence devient un objet, plusieurs deviennent un tableau. Configurez votre parseur pour traiter les éléments répétables connus toujours en tableau, ou normalisez avec [].concat(value) après parsing.

Que devient le texte d’un élément qui a aussi des attributs ?

Il est stocké sous la clé réservée #text, puisque l’objet héberge déjà les attributs. Un élément avec uniquement du texte se réduit à une simple chaîne.

Comment gérer les namespaces XML ?

JSON n’a pas de namespaces. L’approche la plus sûre garde le préfixe dans la clé ("soap:Envelope") et les déclarations xmlns comme attributs @xmlns:*, pour ne rien perdre.

Outils et guides liés