XML vs JSON: rozdíly a kdy co použít

XML i JSON jsou textové formáty pro strukturovaná data, ale vycházejí z jiných představ o tom, jak data vypadají. Kapitola srovnává jejich datový model, nástroje a bezpečnost a ukazuje, na co si dát pozor při převodu mezi nimi.

Autor: Aktualizováno

Stejná data dvakrát

Objednávka zapsaná v XML:

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:

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

VlastnostXMLJSON
Datový modelstrom elementů s atributy a textemobjekty, pole a hodnoty
Datové typyvše je text; typy dodá až schémařetězec, číslo, true/false, null
Poleopakované elementy se stejným jménemnativní typ []
Atributyanone, jen vlastnosti objektu
Smíšený obsah (text + značky)ano, přirozenějen obtížnými konvencemi
Komentářeanone; povolují je až nestandardní dialekty JSONC a JSON5
Jmenné prostoryanone
SchémaDTD, XSD, RELAX NG, SchematronJSON Schema
Dotazy a transformaceXPath, XQuery, XSLTJSONPath, JMESPath, jq
Velikost zápisuvětší (uzavírací značky)menší
Práce v JavaScriptupřes DOMParser a DOMJSON.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:
XML s jednou položkou
<polozky>
  <polozka>Hrnek</polozka>
</polozky>
Výsledek převodu podle počtu položek
{ "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, null a chybějící hodnota. Převodník obvykle udělá z <poznamka/> prázdný řetězec nebo null podle vlastní konvence. Atribut xsi:nil zná 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.