TypesXML - XML Processing Library for TypeScript

TypesXML logo

TypesXML is a TypeScript / Node.js XML library for parsing, validating, and processing XML documents. It provides both DOM and streaming (SAX) APIs, along with support for DTD, XML Schema 1.0 and RelaxNG validation and XML Catalog resolution.

TypesXML is a native TypeScript XML library with published results on the official W3C suites: 100% on the XML DTD test suite and 96.7% on the XML Schema 1.0 suite (~40,000 tests). It also passes 100% of a RelaxNG test suite. Among native TypeScript XML libraries, it is the only one known to publish comparable W3C conformance results.

The source code is available on GitHub under the Eclipse Public License v1.0. Developers can clone, adapt, and ship the library under the terms of that license, or contact Maxprograms for commercial arrangements.

Quick example

Parse an XML file and build a DOM document:

import { DOMBuilder, SAXParser } from "typesxml";

const handler = new DOMBuilder();
const parser = new SAXParser();

parser.setContentHandler(handler);
parser.parseFile("example.xml");

const document = handler.getDocument();
console.log(document.toString());

Why TypesXML

Most XML tools in JavaScript ecosystems fall into one of three categories: DOM-based models that are easy to use but memory-heavy and unpredictable for large documents, lightweight parsers that expose raw streaming events without a structured model on top, or wrappers around native C/C++ parsers that need a compiler toolchain or prebuilt binaries for each platform.

TypesXML sits between these extremes. It is built on a SAX-style foundation but exposes a strongly structured, TypeScript-friendly model that stays predictable even for large and complex XML formats such as TMX and XLIFF.

  • Streaming-oriented processing without requiring full in-memory document trees
  • Structured access to XML data while preserving parsing determinism
  • Native support for DTD, XML Schema and RelaxNG validation workflows
  • Designed for backend and tooling scenarios, not browser DOM manipulation

TypesXML is not intended to replace general-purpose XML libraries. It is focused specifically on cases where XML is a data interchange format with strict structural requirements and large-scale processing needs.

Features

Core capabilities for parsing, validation, and integration of XML documents:

Parsing

  • DOM builder (DOMBuilder) for in-memory document trees with lexical preservation
  • Streaming SAX parser with file, string, and Node.js stream support

Validation

  • Complete DTD parser/validator (including conditional sections and parameter entities)
  • XML Schema 1.0 validation with support for complex types
  • RelaxNG validation (XML syntax), including XML Schema datatypes and ID/IDREF checks
  • Strict XML 1.0 / 1.1 character validation

Integration

  • OASIS XML Catalog resolver for public/system identifiers
  • XML ↔ JSON conversion (lightweight and lossless modes)

Compliance

  • 100% W3C XML DTD test suite
  • 96.7% W3C XML Schema test suite
  • 100% RelaxNG test suite

SAX Parser

SAXParser drives any ContentHandler implementation. A handler receives structured callbacks during parsing:

interface ContentHandler {
    initialize(): void;
    setCatalog(catalog: Catalog): void;
    startDocument(): void;
    endDocument(): void;
    xmlDeclaration(version: string, encoding: string, standalone: string | undefined): void;
    startElement(name: string, atts: XMLAttribute[]): void;
    endElement(name: string): void;
    internalSubset(declaration: string): void;
    characters(text: string): void;
    ignorableWhitespace(text: string): void;
    comment(text: string): void;
    processingInstruction(target: string, data: string): void;
    startCDATA(): void;
    endCDATA(): void;
    startDTD(name: string, publicId: string, systemId: string): void;
    endDTD(): void;
    skippedEntity(name: string): void;
    getGrammar(): Grammar | undefined;
    setGrammar(grammar: Grammar | undefined): void;
    getCurrentText(): string;
}
                    

The built-in DOMBuilder implements this interface to provide DOM support out of the box.

Usage

import { DOMBuilder, SAXParser } from "typesxml";

const handler = new DOMBuilder();
const parser = new SAXParser();
parser.setContentHandler(handler);

// Parse from a file
parser.parseFile("example.xml");
const document = handler.getDocument();
console.log(document.toString());

// Parse from a string
parser.parseString("");

// Parse from a stream
// await parser.parseStream(fs.createReadStream("example.xml"));

To enable XML Catalog resolution or validation, configure the parser before invoking parse* methods:

parser.setCatalog(myCatalog);
parser.setValidating(true); // Turns on DTD, XML Schema and RelaxNG validation

Caching grammars

When you parse many documents that share the same DTD, XML Schema or RelaxNG grammar, parsing the grammar once per document is wasteful. Pass a GrammarCache to the parser to parse each grammar only once per run:

import { DOMBuilder, GrammarCache, SAXParser } from "typesxml";

const cache = new GrammarCache();
for (const file of files) {
    const handler = new DOMBuilder();
    const parser = new SAXParser();
    parser.setContentHandler(handler);
    parser.setCatalog(myCatalog);
    parser.setGrammarCache(cache);
    parser.parseFile(file);
    // ...
}

The cache is keyed by the resolved grammar URL, so different grammars coexist safely. A grammar fetched from the cache is a copy: document-specific declarations (such as an internal DTD subset) never modify the cached grammar. The caller owns the cache lifetime; create one per batch run and discard it afterwards.

Benchmark

TypesXML was compared with fast-xml-parser and tXml using the same input files and runtime environment. Each result is the best of three runs after a warmup pass. This comparison focuses on parsing speed only, and feature sets and parsing models differ significantly between libraries.

Size: 1.858 MB | Elements: 41,349
Parser            Duration     Throughput   Success
TypesXML          165.20 ms    11.25 MB/s     yes
fast-xml-parser   154.41 ms    12.03 MB/s     yes
tXml               17.19 ms   108.06 MB/s     yes

Size: 63.215 MB | Elements: 817,216
TypesXML         5444.54 ms    11.61 MB/s     yes
fast-xml-parser  4294.62 ms    14.72 MB/s     yes
tXml              555.80 ms   113.74 MB/s     yes

Size: 121.517 MB | Elements: 1,883,407
TypesXML         8530.47 ms    14.25 MB/s     yes
fast-xml-parser  8615.05 ms    14.11 MB/s     yes
tXml             1169.80 ms   103.88 MB/s     yes

Size: 574.672 MB | Elements: 7,853,048
TypesXML        57134.36 ms    10.06 MB/s     yes
fast-xml-parser        n/a        n/a         no
tXml                   n/a        n/a         no

tXml achieves significantly higher throughput on small and medium inputs because it parses from a fully loaded in-memory string and performs minimal processing. For the 574 MB file, both fast-xml-parser and tXml fail with Cannot create a string longer than 0x1fffffe8 characters, because Node.js limits the maximum string size to about 512 MB. TypesXML uses a streaming SAX pipeline and processes input in chunks, so it can handle very large files.

Documentation & Samples

  • Read the step-by-step TypesXML tutorial for guided workflows.
  • Use the JSON and XML Conversion Guide to translate between XML documents and JSON objects, with guidance on when to enable the metadata-preserving round-trip mode.
  • Explore the runnable examples under samples/ to see the code in action.

W3C XML Test Suite

The repository includes code that runs the official W3C XML Conformance Test Suite for DTD and XML Schema grammars, and a test suite for RelaxNG.

DTD

  1. Download the latest archive from the W3C XML Test Suite (e.g., xmlts20080827.zip).
  2. Extract the archive into ./tests/xmltest so the valid, invalid, and not-wf folders sit under that path.
  3. Install dependencies if needed: npm install.
  4. Run the test suite: npm run testDtd

The script compiles the TypeScript sources and executes ts/tests/DTDTestSuite.ts, reporting any conformance failures.

XML Schema

TypesXML currently passes 96.7% of the W3C XML Schema Test Suite (2006 edition, ~40,000 tests), the only native TypeScript implementation of XML Schema 1.0 validated against the official W3C test suite.

  1. Download the latest archive from the XML Schema Version 1.0, 2nd Edition.
  2. Extract the archive into ./tests/ so the test cases are available under ./tests/xmlschema2006-11-06.
  3. Install dependencies if needed: npm install.
  4. Run the test suite: npm run testXmlSchema

The script compiles the TypeScript sources and executes ts/tests/XmlSchemaTestSuite.ts, reporting any conformance failures.

RelaxNG

TypesXML passes 100% of the RelaxNG test suite. The suite is a single file, spectest.xml, with test cases that check whether a schema is correct or incorrect and whether instance documents are valid or invalid against it.

  1. Download spectest.xml.
  2. Save it as ./tests/relaxng/spectest.xml.
  3. Install dependencies if needed: npm install.
  4. Run the test suite: npm run testRelaxNG

The script compiles the TypeScript sources and executes ts/tests/RelaxNGTestSuite.ts. It prints every failing test case, followed by a summary with the number of passed checks. To run a single test case, set the RNG_CASE environment variable to its position in the file, for example RNG_CASE=42 node dist/cjs/tests/RelaxNGTestSuite.js.