Načtení XML: DOMParser
Text s XML převede na dokument objekt DOMParser. Výsledek je stejný
Document, jaký znáš z HTML stránky, takže na něm fungují známé metody jako
getElementsByTagName, getAttribute nebo textContent.
const text = `<objednavka cislo="2026-117">
<polozka mnozstvi="2">Hrnek</polozka>
<polozka mnozstvi="1">Talíř</polozka>
</objednavka>`;
const doc = new DOMParser().parseFromString(text, 'application/xml');
const root = doc.documentElement;
console.log(root.getAttribute('cislo')); // "2026-117"
for (const polozka of root.getElementsByTagName('polozka')) {
console.log(polozka.textContent, polozka.getAttribute('mnozstvi'));
}
Druhý argument je typ obsahu a rozhoduje o tom, jaký parser se použije. Pro XML to musí být
application/xml (nebo text/xml, případně
image/svg+xml). S text/html by prohlížeč text četl jako HTML: chyby
by tiše opravil, názvy elementů převedl na malá písmena a samo-uzavírací značky by nerozpoznal.
| Úkol | API v prohlížeči |
|---|---|
| Text → dokument | new DOMParser().parseFromString(text, "application/xml") |
| Kořenový element | doc.documentElement |
| Elementy podle jména | getElementsByTagName(), getElementsByTagNameNS(), querySelector() |
| Atributy a text | getAttribute(), setAttribute(), textContent |
| Dotaz XPath 1.0 | doc.evaluate(výraz, uzel, resolver, typ, null) |
| Nový dokument | document.implementation.createDocument(ns, "koren", null) |
| Dokument → text | new XMLSerializer().serializeToString(doc) |
Jak poznat chybu zápisu
DOMParser při chybě nevyhodí výjimku. Vrátí dokument, ve kterém je
místo dat element <parsererror> s popisem chyby. Kdo to nekontroluje, pracuje
pak s prázdnými výsledky a neví proč. Kontrola proto patří hned za každé parsování:
function parseXml(text) {
const doc = new DOMParser().parseFromString(text, 'application/xml');
const error = doc.querySelector('parsererror');
if (error) throw new Error(error.textContent);
return doc;
}
parseXml('<a><b></a>'); // Error: … Unexpected closing tag: a != b …
Text hlášky se liší podle prohlížeče: Chrome od verze 151 používá parser napsaný v Rustu,
Safari knihovnu libxml2 a Firefox vlastní parser. Význam hlášek vysvětluje kapitola Jak funguje
XML. Funkci parseXml používají i další ukázky na této stránce.
Načtení souboru ze serveru nebo z disku
Soubor ze serveru stáhni přes fetch a text předej parseru. Soubor, který vybral
uživatel, přečteš metodou file.text() — nikam se neodesílá, všechno proběhne v
prohlížeči.
// soubor ze serveru
const response = await fetch('/data/objednavky.xml');
const doc = parseXml(await response.text());
// soubor, který uživatel vybral v <input type="file">
const file = input.files[0];
const doc2 = parseXml(await file.text());
Starší XMLHttpRequest umí XML rozparsovat sám a výsledek vrátí ve vlastnosti
responseXML; v novém kódu je jednodušší fetch s
DOMParserem. Při čtení z jiné domény platí běžná pravidla CORS.
Vytvoření XML a převod zpět na text
Nový dokument vytvoříš přes document.implementation.createDocument, elementy přes
createElementNS a na text ho převede XMLSerializer. Oproti skládání
textu z řetězců má tahle cesta velkou výhodu: znaky < a & v
datech se escapují samy.
const NS = 'http://example.cz/faktura';
const doc = document.implementation.createDocument(NS, 'faktura', null);
const cislo = doc.createElementNS(NS, 'cislo');
cislo.textContent = 'FV2026-042 & spol.'; // & se při uložení zapíše jako &
doc.documentElement.append(cislo);
const xml = new XMLSerializer().serializeToString(doc);
// <faktura xmlns="http://example.cz/faktura"><cislo>FV2026-042 & spol.</cislo></faktura> XMLSerializer nepřidá deklaraci <?xml …?> a výstup
neodsazuje. Deklaraci si podle potřeby připoj sám; pro čitelný výstup použij
formátovač.
Bezpečnost: text z XML nevkládej do stránky přes innerHTML.
Soubor od cizího odesílatele může v textu nést HTML se skriptem. Použij
textContent, které text vloží jako text.
Serializace XML
Při převodu XML stromu na text (serializaci) knihovna zapíše zvláštní znaky podle pravidel XML, například ampersand jako &. Zápis zpět nemusí zachovat původní prefixy, odsazení, CDATA nebo pořadí atributů; testuj obsah a požadované kódování.
new XMLSerializer().serializeToString(doc); DOM
DOMParser vrací Document se stromem uzlů. Pro jmenné prostory používej createElementNS a getElementsByTagNameNS; neporovnávej pouze prefix. Text vkládej přes textContent.
Streamové čtení XML
DOMParser načítá celý dokument; standardní rozhraní prohlížeče neposkytuje SAX parser pro čtení po událostech. V Node.js zvol streamový XML parser a zpracovávej data z createReadStream postupně po událostech. Při předávání výsledků dál čekej, až je výstup připraven přijmout; tomu se říká backpressure. JSON.parse také potřebuje celý text; velké JSON seznamy vyžadují jiný parser nebo formát po záznamech.
XPath: document.evaluate
Na složitější dotazy má prohlížeč vestavěný XPath. Metoda
evaluate přijme výraz, výchozí uzel, funkci pro překlad prefixů, požadovaný typ
výsledku a nepovinně objekt k opakovanému použití:
const result = doc.evaluate(
'/objednavka/polozka[@mnozstvi > 1]', // výraz XPath 1.0
doc, // uzel, od kterého se hledá
null, // resolver prefixů (bez jmenných prostorů null)
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
null,
);
for (let i = 0; i < result.snapshotLength; i++) {
console.log(result.snapshotItem(i).textContent); // "Hrnek"
}
// jedna hodnota
doc.evaluate('count(//polozka)', doc, null, XPathResult.NUMBER_TYPE, null).numberValue; // 2
// se jmenným prostorem: resolver převede prefix na URI
const resolver = (prefix) => (prefix === 'f' ? 'http://example.cz/faktura' : null);
doc.evaluate('//f:cislo', doc, resolver, XPathResult.STRING_TYPE, null).stringValue;
Prohlížeče umí jen XPath 1.0. Funkce z novějších verzí (například
matches() nebo format-date()) skončí chybou. Výrazy pro jmenné
prostory potřebují přiřazení prefixů k URI (resolver) i tehdy, když dokument používá výchozí jmenný prostor bez prefixu —
v XPath 1.0 si pro něj vymysli vlastní prefix.
Jmenné prostory
Jakmile dokument používá jmenné prostory, hledej elementy podle
URI jmenného prostoru a lokálního jména metodou getElementsByTagNameNS. Hledání
podle prefixu (f:cislo) funguje jen náhodou — stejný dokument může mít jiný prefix
nebo výchozí jmenný prostor bez prefixu a kód pak přestane fungovat.
const text = `<f:faktura xmlns:f="http://example.cz/faktura">
<f:cislo>FV2026-042</f:cislo>
</f:faktura>`;
const doc = parseXml(text);
const NS = 'http://example.cz/faktura';
doc.getElementsByTagNameNS(NS, 'cislo')[0].textContent; // "FV2026-042"
doc.getElementsByTagName('f:cislo').length; // 1 — ale jen s tímhle prefixem
doc.querySelector('cislo'); // najde, ale v jakémkoli jmenném prostoru querySelector('cislo') element najde, protože selektor bez prefixu bere v úvahu
jen lokální jméno. Neumí ale odlišit dva slovníky se stejným názvem elementu (třeba
<nazev> zboží a <nazev> dodavatele), a proto se hodí jen
pro dokumenty bez jmenných prostorů. Velikost písmen rozlišuje, stejně jako XML.
Validace proti XSD
Prohlížečové DOMParser nemá XSD validaci. Použij knihovnu, například xmllint ve WebAssembly jako nástroj XML.cz, nebo serverový validátor. Ověř podporovanou verzi XSD a zakázané externí zdroje.
Bezpečné nastavení parseru
Nezobrazuj nedůvěryhodné XML přes innerHTML. Serverové knihovny konfiguruj zvlášť proti externím entitám a DTD podle XXE. Omez velikost vstupu a čas zpracování. Bezpečné nastavení prohlížeče není nastavení Node.js.
Jak prohlížeč zobrazí samotný XML soubor
Když XML soubor otevřeš přímo v prohlížeči, záleží na tom, co obsahuje:
| Co XML soubor obsahuje | Co prohlížeč zobrazí |
|---|---|
| nic navíc | strom elementů a nad ním upozornění, že soubor nemá styl |
| <?xml-stylesheet type="text/css" href="…"?> | dokument naformátovaný podle CSS jako běžnou stránku |
| <?xml-stylesheet type="text/xsl" href="…"?> | výsledek transformace XSLT — v Chromu jen do verze 157 |
| chybu zápisu | chybovou hlášku s číslem řádku místo obsahu |
Styl připojuje instrukce pro zpracování <?xml-stylesheet?>. Varianta s CSS funguje dál, varianta s XSLT ale končí:
Chrome od verze 158 (17. listopadu 2026) přestane XSLT podporovat, včetně objektu
XSLTProcessor v JavaScriptu. Firefox a Safari odstranění plánují také. Kód, který
XSLTProcessor používá, zachráníš knihovnou
xslt-polyfill (libxslt ve WebAssembly),
další náhrady najdeš v kapitole XSLT.
A co Node.js?
Node.js DOMParser, XMLSerializer ani document.evaluate
nemá — jsou to rozhraní prohlížeče. Na serveru sáhni po knihovně: @xmldom/xmldom
nabízí stejné DOM API jako prohlížeč, fast-xml-parser převádí XML rovnou na
objekty JavaScriptu. Pro validaci proti XSD a XSLT se používají vazby na libxml2 nebo SaxonJS.
Načtení JSON
JSON parser vrací datovou strukturu, ne XML strom. Chyby syntaxe zpracuj jako chyby vstupu; data ověř také strukturálně.
const text = '{"jmeno":"Jana","vek":20}';
const data = JSON.parse(text);
console.log(data.jmeno); Vytvoření JSON
Vytvoř hodnotu v paměti a nech její textový zápis na knihovně.
const data = { jmeno: 'Jana', vek: 20, aktivni: true }; Serializace JSON
Neskládej text ručně. Ověř přesnost čísel, reprezentaci dat a chování nečíselných hodnot.
const text = JSON.stringify(data, null, 2); JSON Schema
Standardní knihovna neposkytuje plnou validaci JSON Schema. Vyber knihovnu s podporou požadované verze pravidel JSON Schema z oficiální dokumentace či katalogu. Základy a rozdíly verzí vysvětluje kurz JSON Schema.
Ukázka vyžaduje instalaci uvedeného balíčku. Kontrola format závisí na nastavení knihovny; validace nenahrazuje obchodní pravidla.
import { Validator } from '@cfworker/json-schema';
const schema = { type: 'object', properties: { vek: { type: 'integer' } }, required: ['vek'] };
const result = new Validator(schema, '2020-12').validate({ vek: 20 });
console.log(result.valid); Dokumentace API
Příklady JSON vycházejí z oficiální dokumentace jazyka. Překlady typů, maximální hloubka a chování při chybě jsou vlastnosti knihovny, ne samotné syntaxe JSON.
JSON Schema: ověření skutečných vstupních dat
import {Validator} from "@cfworker/json-schema";
const validator = new Validator({
$schema: "https://json-schema.org/draft/2020-12/schema",
type: "object", required: ["id"],
properties: {id: {type: "string", pattern: "^[0-9]{3}$"}},
additionalProperties: false
});
for (const text of ['{"id":"001"}', '{"id":1}', '{"id":"001","admin":true}']) {
const result = validator.validate(JSON.parse(text));
console.log(result.valid);
} Výsledek je true, false, false. JSON.parse ověřilo všechny tři texty syntakticky; až schéma odmítlo číslo a neočekávané pole. V prohlížeči nelze holý import názvu npm balíčku použít bez bundleru či import mapy. Tento příklad spouštěj v Node.js jako .mjs nebo začleň do svého sestavení.
Schéma nevytváří oprávnění a nemění typy. Identifikátor 001 zůstává text. Pro práci se soubory a streamy navazuje Node.js / TypeScript kapitola.