XML a JSON v Node.js a TypeScriptu

Node.js má vestavěné čtení souborů a JSON, ale pro XML potřebuje knihovnu. TypeScript kontroluje zdrojový kód; nedůvěryhodná vstupní data musíš validovat za běhu.

Autor: Aktualizováno

1. Načtení XML

Pro DOM zvol například @xmldom/xmldom, pro události saxes. Instaluj udržovanou verzi a sleduj chyby parseru. Node neobsahuje prohlížečové DOMParser jako obecný vestavěný XML parser.

2. Vytvoření XML

Vytvářej uzly a text knihovnou místo spojování vstupů do značek. Identifikátor elementu a namespace řeš odděleně; textový escape není validace jména.

3. Serializace XML

Dom knihovna poskytuje XMLSerializer. Po serializaci ověř výstup a kódování při zápisu. Konkrétní DOM ukázky jsou ve společné JavaScript kapitole.

4. DOM

DOM drží celý dokument v paměti. Způsob načtení, hlášení chyb a resolver se v Node knihovně nemusí shodovat s prohlížečem; testuj na cílové implementaci.

5. Streamové čtení

Po instalaci saxes spusť tento ESM příklad nad souborem UTF-8. Čte po blocích a počítá elementy podle local; handler error ukončí parsování. Kontrola počtu bajtů v ukázce používá UTF-8 velikost dekódovaných bloků. Při přenosu přes HTTP omez také původní a rozbalené tělo.

5. Streamové čtení
import { createReadStream } from "node:fs";
import { SaxesParser } from "saxes";
const parser = new SaxesParser({ xmlns: true });
let bytes = 0;
let count = 0;
parser.on("opentag", tag => { if (tag.local === "kniha") count++; });
parser.on("error", error => { throw error; });
for await (const chunk of createReadStream("katalog.xml", { encoding: "utf8" })) {
  bytes += Buffer.byteLength(chunk);
  if (bytes > 10 * 1024 * 1024) throw new Error("Limit vstupu");
  parser.write(chunk);
}
parser.close();
console.log(count);

6. XPath

Vyber procesor podle verze XPath, například FontoXPath pro XPath 3.1. Saxes sám dotazy XPath neprovádí. U streamu musíš požadované informace získávat z událostí nebo vytvořit vybraný podstrom.

7. Validace XSD

Node nemá standardní vestavěný XSD validátor. Zvol prověřený wrapper libxml2 nebo oddělený procesor s řízeným přístupem ke schématům. XML parser a XSD validátor jsou odlišné kroky.

8. Bezpečný parser

Prověř DTD, externí zdroje, hloubku a velikost. V událostech sleduj namespace URI, nejen local, pokud může vstup obsahovat více slovníků. Nespoléhej na to, že každý balíček označený XML má stejné bezpečné výchozí nastavení.

9. Načtení JSON

ReadFile načte celý soubor; vhodný je pro omezené velikosti. JSON.parse může vrátit i null nebo číslo. V TypeScriptu začni typem unknown, ne tvrzením as Kniha bez runtime kontroly.

9. Načtení JSON
import { readFile } from "node:fs/promises";
const value: unknown = JSON.parse(await readFile("data.json", "utf8"));
if (typeof value !== "object" || value === null || Array.isArray(value)) {
  throw new Error("Očekávám objekt");
}

10. Vytvoření JSON

Vytvoř objekt s dohodnutými poli. Identifikátory přesahující bezpečný rozsah Number použij jako řetězce. Datový model TypeScriptu sám nepředepisuje JSON Schema.

11. Serializace JSON

JSON.stringify vytvoří text, writeFile jej zapíše jako UTF-8. BigInt bez explicitní konverze vyvolá chybu. Undefined může v objektu vynechat položku, proto definuj pravidla pro nepřítomnost a null.

12. JSON Schema

Pro 2020-12 lze použít @cfworker/json-schema, který používá i tento web. Validuj unknown před použitím ve vlastním modelu. Schéma neřeší oprávnění. Ověř také podporu format a vzdálených referencí v konkrétní konfiguraci.

Dokumentace

Node.js fs · TypeScript: typy a type assertions · Node.js streams.

DOM: načtení, úprava a zápis celého dokumentu

dom-demo.mjs — npm install @xmldom/xmldom; pevný dobře utvořený vstup
import {DOMParser, XMLSerializer} from "@xmldom/xmldom";
import {writeFile} from "node:fs/promises";
const xml = '<kniha xmlns="urn:knihy" id="k1"><nazev>XML</nazev></kniha>';
const doc = new DOMParser().parseFromString(xml, "application/xml");
const title = doc.getElementsByTagNameNS("urn:knihy", "nazev").item(0);
if (!title) throw new Error("Chybí název");
title.textContent = "XML & JSON";
const note = doc.createElementNS("urn:knihy", "poznamka");
note.textContent = "Vytvořeno DOM API";
doc.documentElement.appendChild(note);
const output = new XMLSerializer().serializeToString(doc);
await writeFile("copy.xml", output, "utf8");
console.log(output);

Výstup obsahuje název XML & JSON s escapovaným ampersandem a nový element poznamka ve stejném namespace. Hledání podle URI a lokálního jména funguje i po změně prefixu. TextContent zapisuje text, nikoli markup. Pro nedůvěryhodný vstup nastav chybové zpracování parseru podle API konkrétní verze; tento příklad demonstruje práci se známou konstantou.

JSON: čtení, runtime validace a serializace

json-demo.mjs — npm install @cfworker/json-schema
import {readFile, writeFile} from "node:fs/promises";
import {Validator} from "@cfworker/json-schema";
const schema = {
  $schema: "https://json-schema.org/draft/2020-12/schema",
  type: "object", required: ["id", "nazev"],
  properties: {id:{type:"string"}, nazev:{type:"string",minLength:1}},
  additionalProperties: false
};
const validator = new Validator(schema);
const data = JSON.parse(await readFile("kniha.json", "utf8"));
const result = validator.validate(data);
if (!result.valid) throw new Error(JSON.stringify(result.errors));
const updated = {...data, nazev: "XML & JSON"};
await writeFile("copy.json", JSON.stringify(updated, null, 2), "utf8");
console.log(updated.id, updated.nazev);
kniha.json pro tento samostatný program
{"id":"k1","nazev":"XML"}

Spusť node json-demo.mjs: výstup je k1 XML & JSON a copy.json obsahuje upravený objekt. Změna id na číslo poruší type. Přidání admin poruší additionalProperties. Kompilovaný validátor znovu používej pro další záznamy, místo vytváření pro každé pole.

TypeScript interface ani as Kniha runtime chybu neodhalí. Po validaci můžeš spojit schéma s typovaným modelem vhodným adaptérem, ale nevynechávej skutečné ověření vstupu. U readFile nejdřív stanov aplikační limit; pro rozsáhlé soubory použij streamový model. API validátoru dokumentuje cfworker.