Stejná data dvakrát
Objednávka zapsaná v XML:
<objednavka xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" cislo="2026-117">
<zaplaceno>true</zaplaceno>
<polozky>
<polozka mnozstvi="2">Hrnek</polozka>
<polozka mnozstvi="1">Podtácek</polozka>
</polozky>
<poznamka xsi:nil="true"/>
</objednavka> a v JSON:
{
"cislo": "2026-117",
"zaplaceno": true,
"polozky": [
{ "nazev": "Hrnek", "mnozstvi": 2 },
{ "nazev": "Podtácek", "mnozstvi": 1 }
],
"poznamka": null
}
Na první pohled jde o totéž, ale pod povrchem se liší. V JSON je true logická
hodnota a 2 číslo; v XML je obojí text, dokud schéma neřekne jinak. JSON má pole,
XML jen opakuje element polozka. A číslo objednávky je v XML atribut, zatímco
JSON rozdíl mezi atributem a potomkem nezná.
Pozor na prázdnou hodnotu. JSON má samostatný literál null, XML ne. Prázdný
element <poznamka/> znamená prázdný text, tedy "", ne
„žádná hodnota“. Obdobou null je až atribut xsi:nil="true" z XML
Schema, který smí stát jen u elementu deklarovaného ve schématu jako
nillable="true". Druhou možností je element úplně vynechat.
Srovnání v tabulce
| Vlastnost | XML | JSON |
|---|---|---|
| Datový model | strom elementů s atributy a textem | objekty, pole a hodnoty |
| Datové typy | vše je text; typy dodá až schéma | řetězec, číslo, true/false, null |
| Pole | opakované elementy se stejným jménem | nativní typ [] |
| Atributy | ano | ne, jen vlastnosti objektu |
| Smíšený obsah (text + značky) | ano, přirozeně | jen obtížnými konvencemi |
| Komentáře | ano | ne; povolují je až nestandardní dialekty JSONC a JSON5 |
| Jmenné prostory | ano | ne |
| Schéma | DTD, XSD, RELAX NG, Schematron | JSON Schema |
| Dotazy a transformace | XPath, XQuery, XSLT | JSONPath, JMESPath, jq |
| Velikost zápisu | větší (uzavírací značky) | menší |
| Práce v JavaScriptu | přes DOMParser a DOM | JSON.parse, přímo objekty |
Kdy zvolit XML
- Dokumenty se smíšeným obsahem — text, ve kterém jsou vyznačená slova, odkazy nebo poznámky. Tohle JSON neumí přirozeně zapsat:
<odstavec>Cena je <b>199 Kč</b> včetně <abbr title="daň z přidané hodnoty">DPH</abbr>.</odstavec> - Formát je daný — elektronické faktury (ISDOC), kancelářské dokumenty, SVG, RSS, sitemapy, SOAP rozhraní bank a úřadů. Tady se nevybírá.
- Přesně předepsaný formát dat mezi systémy — XSD s datovými typy, jmennými prostory a verzováním je vyzrálý ekosystém, který řada institucí vyžaduje.
- Transformace do více výstupů — XSLT převede stejná data na HTML, PDF (přes XSL-FO) nebo jiný XML formát.
Kdy zvolit JSON
- Webová a mobilní API — JavaScript ho načte jedním voláním
JSON.parse()rovnou do objektů a knihovny pro něj má každý jazyk. - Data odpovídající objektům v kódu — záznamy, seznamy, nastavení. Mapování je přímočaré a bez konvencí.
- Menší objem přenášených dat — bez uzavíracích značek je zápis kratší, i když po kompresi (gzip, Brotli) se rozdíl výrazně zmenší.
- Konfigurace a ukládání dokumentů v NoSQL databázích, které s JSON pracují nativně.
Úskalí převodu mezi XML a JSON
Neexistuje jediný „správný“ převod. Každá knihovna používá vlastní konvenci (například
BadgerFish nebo převod, kde atributy dostanou prefix @) a výsledky se liší. Typické
problémy:
- Jedna položka vs. pole. Převodník nepozná, že element se může opakovat. Jedna položka se převede na objekt, dvě na pole — a kód, který čeká pole, spadne:
<polozky>
<polozka>Hrnek</polozka>
</polozky> { "polozky": { "polozka": "Hrnek" } } // jedna položka → objekt
{ "polozky": { "polozka": ["Hrnek", "Talíř"] } } // dvě položky → pole - Typy. Z XML přijde
"2"jako text; převodník musí hádat, jestli jde o číslo. Hádání škodí u PSČ, telefonů nebo kódů s nulou na začátku. - Atributy a text zároveň. Element s atributem i textem
(
<cena mena="CZK">199</cena>) potřebuje v JSON umělý klíč pro text, například"#text"nebo"$". - Pořadí a smíšený obsah. V XML záleží na pořadí sourozenců; vlastnosti JSON objektu pořadí z hlediska specifikace nemají.
- Prázdný element,
nulla chybějící hodnota. Převodník obvykle udělá z<poznamka/>prázdný řetězec nebonullpodle vlastní konvence. Atributxsi:nilzná jen převod řízený schématem. - Komentáře, jmenné prostory a instrukce se při převodu obvykle ztratí.
Pokud převod jen jednorázově potřebuješ, vyzkoušej záložku Převody v našem XML nástroji, která nabízí několik konvencí vedle sebe. Pro trvalé rozhraní je lepší převod napsat ručně podle schématu.
Bezpečnost
XML parsery umí zpracovat DTD a externí entity, což otevírá útoky typu XXE a „billion laughs“.
Jak je v jednotlivých jazycích vypnout, ukazuje kapitola
XXE: útok přes externí entity. JSON takové mechanismy nemá, ale ani u něj
se data nesmí vyhodnocovat jako kód. Vždy použij JSON.parse(), nikdy
eval(). U dat z cizích zdrojů hlídej i velikost vstupu a hloubku vnoření a
dlouhá čísla (ID) přenášej jako řetězce, protože JavaScript přesně uloží celá čísla jen do
253.