Convertire XML in JSON sembra meccanico finché non inciampi nelle parti dell'XML per cui JSON non ha un equivalente diretto: attributi, contenuto misto di testo ed elementi, elementi che appaiono una o più volte e namespace. Non c'è un unico mapping „corretto“ —— solo convenzioni. Questa guida spiega le convenzioni standard, le decisioni da prendere e come convertire XML in JSON in JavaScript, Python e nel browser.
Il mapping a colpo d'occhio
La maggior parte dei convertitori XML→JSON (xmltodict, fast-xml-parser e lo strumento di questo sito) segue la stessa forma: ogni elemento diventa un oggetto, gli attributi diventano chiavi con prefisso speciale e il testo diventa il valore o una chiave riservata.
<!-- XML -->
<note id="1" priority="high">
<to>Ada</to>
<from>Bob</from>
<body>Hello & welcome</body>
</note>// JSON
{
"note": {
"@id": "1",
"@priority": "high",
"to": "Ada",
"from": "Bob",
"body": "Hello & welcome"
}
}Attributi → chiavi con prefisso @
Gli oggetti JSON non hanno nozione di attributo, quindi la convenzione quasi universale è prefissare @ ai nomi di attributo. Questo li distingue dagli elementi figli e rende reversibile il mapping.
<book id="b1" lang="en"/>
→ { "book": { "@id": "b1", "@lang": "en" } } Alcuni strumenti usano un altro prefisso ($, _) o un oggetto annidato "@attributes". Scegline uno e applicalo in modo coerente —— il codice che lo consuma deve sapere dove sono gli attributi.
Nodi di testo e contenuto misto
Quando un elemento contiene solo testo, si riduce a un valore stringa. Ma quando ha attributi e testo, il testo serve un posto —— per convenzione, la chiave #text.
<price currency="USD">9.99</price>
→ { "price": { "@currency": "USD", "#text": "9.99" } }
<title>Effective TypeScript</title>
→ { "title": "Effective TypeScript" }Il contenuto davvero misto (testo intervallato con elementi figli, come in markup tipo HTML) è il caso più difficile —— la maggior parte dei convertitori orientati ai dati concatena o scarta il testo libero. Se il tuo XML è di stile documento invece che dati, qui aspettati perdita.
Il problema uno vs array
Questa è la trappola che rompe più codice di ogni altra. Un elemento che appare una volta diventa un oggetto; lo stesso elemento che appare due volte diventa un array. La forma JSON dipende dai dati, non dallo schema:
<tags><tag>a</tag></tags>
→ { "tags": { "tag": "a" } } // oggetto
<tags><tag>a</tag><tag>b</tag></tags>
→ { "tags": { "tag": ["a", "b"] } } // array I consumer che si aspettano tags.tag come array si romperanno sempre con un singolo elemento. Due soluzioni: configura il parser per trattare elementi ripetibili noti sempre come array, oppure normalizza dopo il parse (const arr = [].concat(node.tag ?? [])).
Namespace
I namespace XML usano prefissi (soap:Envelope) legati da dichiarazioni xmlns. JSON non ha concetto di namespace, quindi i convertitori tendono a una di queste strategie:
- Mantenere il prefisso nella chiave ——
"soap:Envelope". Semplice e reversibile, ma la chiave contiene due punti e dovrai accedervi con bracket (obj["soap:Envelope"]). - Rimuovere il prefisso ——
"Envelope". Chiavi più pulite, ma perdi il namespace e rischi collisioni tra due namespace che condividono lo stesso nome locale. - Mantenere
xmlnscome attributi —— le dichiarazioni diventano chiavi"@xmlns:soap"perché il binding sopravviva al round-trip.
Per la maggior parte dei compiti di dati, mantenere il prefisso nella chiave è il default più sicuro —— non perde mai informazione.
Entità e CDATA
Un convertitore corretto decodifica le cinque entità predefinite (<, >, &, ", ') e i riferimenti numerici (©) nei loro caratteri, e tratta i blocchi <![CDATA[...]]> come testo letterale.
Convenzioni nominate: BadgerFish, GData, Parker
La mappatura „@ per attributi / #text per testo“ non è l'unica in circolazione. Tre convenzioni nominate che vedrai leggendo output XML→JSON di altri sistemi:
- BadgerFish —— attributi sotto chiave con prefisso
@; testo sotto$; dichiarazioni di namespace sotto@xmlns. Verbosa ma senza perdita. - GData —— variante di Google: attributi con prefisso
$; testo sotto$t; gli elementi ripetuti sono sempre array. Senza perdita e con forma prevedibile. - Parker —— scarta del tutto gli attributi; il mapping più semplice e con più perdita. Utile quando controlli entrambi i lati e ti interessano solo i valori degli elementi.
Quando integri con un sistema che già produce JSON-da-XML, prima identifica quale convenzione usa, poi scrivi il codice di parsing.
Interrogare il risultato con JSONPath
Una volta convertito l'XML, puoi referenziare valori con JSONPath. Due piccoli aggiustamenti rispetto alle abitudini di XPath:
- Le chiavi attributo portano il prefisso
@del mapping, quindi l'@iddi XPath diventa$..['@id']in JSONPath. - La questione uno-vs-array fa sì che un XPath che funziona come
book/titlepossa dover essere$..book[*].titlein JSONPath per gestire entrambe le forme.
Come convertire XML in JSON nel codice
// JavaScript (browser) —— DOMParser + una piccola visita, o una libreria:
import { XMLParser } from 'fast-xml-parser';
const parser = new XMLParser({ ignoreAttributes: false, attributeNamePrefix: '@' });
const obj = parser.parse(xmlString);
# Python —— xmltodict mappa gli attributi su "@name" e il testo su "#text"
import xmltodict, json
doc = xmltodict.parse(xml_string)
print(json.dumps(doc, indent=2))Converti XML in JSON online
Per una conversione rapida, incolla il tuo XML nel convertitore JSON ⇄ XML e clicca To JSON. Applica le convenzioni di cui sopra —— @ per attributi, #text per contenuto misto, array per elementi ripetuti —— e gira interamente nel browser, così feed interni e payload API non lasciano la tua macchina.
Domande frequenti
Come si rappresentano gli attributi XML in JSON?
Per convenzione, diventano chiavi con prefisso @ (es. @id), distinti dagli elementi figli, perché il mapping possa essere invertito.
Perché lo stesso elemento a volte diventa oggetto e a volte array?
Perché la forma segue i dati: un'occorrenza si mappa a oggetto, più occorrenze a array. Configura il parser per trattare gli elementi ripetibili noti come array, o normalizza con [].concat(value) dopo il parse.
Cosa succede al testo dentro un elemento con attributi?
Va sotto la chiave riservata #text, dato che l'oggetto contiene già gli attributi. Un elemento con solo testo si riduce a una stringa semplice.
Come si gestiscono i namespace XML?
JSON non ha namespace. L'approccio più sicuro mantiene il prefisso nella chiave ("soap:Envelope") e le dichiarazioni xmlns come attributi @xmlns:* per non perdere nulla.
Strumenti e guide correlate
- Convertitore JSON ⇄ XML —— converte in entrambe le direzioni nel browser
- JSON in XML: elementi radice, array e mapping degli attributi —— la direzione inversa
- Come convertire CSV e XML in JSON —— incluso CSV
- Cos'è JSON? —— i tipi e le regole del formato di destinazione