Working with XML in TypeScript: From Parsing to Generation
XML (eXtensible Markup Language) remains one of the key formats for data exchange, configuration files, and document workflows. In the TypeScript ecosystem, several powerful libraries are available that allow you to work with XML efficiently while maintaining strict typing and the benefits of static analysis. In this article, we will review the main tools, their capabilities, and provide practical usage examples.
Why Use TypeScript for Working with XML?
TypeScript adds a type system to JavaScript, which is especially useful when working with XML documents of complex structure. You can describe data schemas through interfaces, avoid errors when accessing nested elements, and automatically get autocompletion in your IDE. Additionally, modern libraries for working with XML have type declarations (typings), making their use as safe as possible.
Main Libraries for Working with XML in TypeScript
- fast-xml-parser — the fastest and most feature-rich library. Supports parsing into objects/arrays, validation, working with attributes, CDATA, and namespaces.
- xml2js — a classic parser that converts XML into JavaScript objects. Supports asynchronous parsing and custom options.
- xmldom — a DOM parser implementation for Node.js and the browser. Allows manipulating the XML tree like in the browser DOM.
- xmlbuilder2 — a modern library for creating XML documents with a chaining API and full type support.
Installing Libraries
To get started, install one of the libraries via npm. All of them have built-in type declarations:
npm install fast-xml-parsernpm install xml2jsnpm install @xmldom/xmldomnpm install xmlbuilder2Example 1: Parsing XML with fast-xml-parser
Let's look at a basic example of parsing an XML string into a typed object:
import { XMLParser } from 'fast-xml-parser';
interface Book { title: string; author: string; year: number; price?: number;}
interface Catalog { catalog: { book: Book | Book[]; };}
const xmlData = ` <catalog> <book> <title>TypeScript Handbook</title> <author>Microsoft</author> <year>2023</year> </book> <book> <title>XML for Developers</title> <author>John Doe</author> <year>2022</year> <price>29.99</price> </book> </catalog>`;
const parser = new XMLParser({ ignoreAttributes: false, attributeNamePrefix: '@_', isArray: (name) => name === 'book',});
const result: Catalog = parser.parse(xmlData);console.log(result.catalog.book[0].title); // "TypeScript Handbook"Note the isArray option — it ensures that the book element is always an array, even if there is only one book in the XML. This simplifies further processing.
Example 2: Creating XML with xmlbuilder2
The xmlbuilder2 library provides a convenient chaining interface for generating XML:
import { create } from 'xmlbuilder2';
interface User { id: number; name: string; email: string;}
const user: User = { id: 42, name: 'Alice', email: 'alice@example.com'};
const doc = create({ version: '1.0', encoding: 'UTF-8' }) .ele('users') .ele('user', { id: user.id.toString() }) .ele('name').txt(user.name).up() .ele('email').txt(user.email).up() .up() .up();
const xmlString: string = doc.end({ prettyPrint: true });console.log(xmlString);/*<?xml version="1.0" encoding="UTF-8"?><users> <user id="42"> <name>Alice</name>