Работа с XML в TypeScript: библиотеки для парсинга и создания XML

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Работа с XML в TypeScript: обзор библиотек и практические примеры

XML (eXtensible Markup Language) остаётся востребованным форматом для обмена данными в корпоративных системах, конфигурационных файлах и веб-сервисах (SOAP, RSS/Atom). В TypeScript, благодаря статической типизации, работа с XML становится более безопасной и предсказуемой. В этой статье мы рассмотрим три основные библиотеки для работы с XML в TypeScript: fast-xml-parser, xml2js и xmlbuilder2. Вы узнаете, как парсить XML, создавать XML-документы и валидировать их структуру.

1. Установка и настройка

Для начала работы установите одну или несколько библиотек через npm:

npm install fast-xml-parser xml2js xmlbuilder2
npm install -D @types/xml2js  // типы для xml2js (для fast-xml-parser типы встроены)

2. Парсинг XML с помощью fast-xml-parser

fast-xml-parser — самая быстрая библиотека для парсинга XML в JavaScript/TypeScript. Она поддерживает работу с атрибутами, пространствами имён и может преобразовывать XML в JSON.

Базовый парсинг

import { XMLParser } from 'fast-xml-parser';

const xmlString = `<bookstore>
  <book category="fiction">
    <title>Война и мир</title>
    <author>Лев Толстой</author>
    <price currency="RUB">1200</price>
  </book>
</bookstore>`;

const parser = new XMLParser({
  ignoreAttributes: false,  // сохранять атрибуты
  attributeNamePrefix: '@_', // префикс для атрибутов
});

const result = parser.parse(xmlString);
console.log(result);

Результат будет объектом:

{
  bookstore: {
    book: {
      '@_category': 'fiction',
      title: 'Война и мир',
      author: 'Лев Толстой',
      price: {
        '@_currency': 'RUB',
        '#text': '1200'
      }
    }
  }
}

Парсинг с типизацией

interface Book {
  '@_category': string;
  title: string;
  author: string;
  price: {
    '@_currency': string;
    '#text': number;
  };
}

interface Bookstore {
  bookstore: {
    book: Book | Book[];
  };
}

const typedResult = parser.parse(xmlString) as Bookstore;
console.log(typedResult.bookstore.book);

3. Парсинг XML с помощью xml2js

xml2js — библиотека с более продвинутыми возможностями, включая поддержку process-функций и кастомных преобразований. Она работает асинхронно.

Асинхронный парсинг

import { parseStringPromise } from 'xml2js';

interface XmlBook {
  $: { category: string };
  title: string[];
  author: string[];
  price: Array<{ $: { currency: string }, _: string }>;
}

async function parseXmlData(xml: string): Promise<void> {
  try {
    const result = await parseStringPromise(xml, {
      explicitArray: false,  // не оборачивать одиночные элементы в массивы
      attrkey: '$',          // ключ для атрибутов
      charkey: '_'           // ключ для текстового содержимого
    });
    
    const book = result.bookstore.book as XmlBook;
    console.log(`Книга: ${book.title}, автор: ${book.author}`);
    console.log(`Цена: ${book.price._} ${book.price.$.currency}`);
  } catch (error) {
    console.error('Ошибка парсинга XML:', error);
  }
}

parseXmlData(xmlString);

4. Создание XML с помощью xmlbuilder2

xmlbuilder2 — современная библиотека для создания XML-документов с поддержкой TypeScript. Она предоставляет цепочечный API и автоматическое экранирование.

Создание простого XML

import { create } from 'xmlbuilder2';

const xml = create({ version: '1.0', encoding: 'UTF-8' })
  .ele('catalog')
    .ele('book', { id: '1', category: 'fiction' })
      .ele('title').txt('Преступление и наказание').up()
      .ele('author').txt('Фёдор Достоевский').up()
      .ele('price', { currency: 'RUB' }).txt('1500').up()
    .up()
    .ele('book', { id: '2', category: 'science' })
      .ele('title').txt('Краткая история времени').up()
      .ele('author').txt('Стивен Хокинг').up()
      .ele('price', { currency: 'USD' }).txt('25').up()
    .up()
  .end({ prettyPrint: true });

console.log(xml);

Результат:

&                    

Рекомендаций