High-performance, pull-based XML parser for JavaScript/TypeScript with declarative converter API
npm install stax-xmlbash
npm
npm install stax-xml
yarn
yarn add stax-xml
pnpm
pnpm add stax-xml
bun
bun add stax-xml
deno
deno add npm:stax-xml
`
$3
Here are basic examples to get started. StAX-XML provides two parsing approaches:
1. Event-based API: Low-level streaming parser for fine-grained control
2. Converter API: Declarative, zod-style schema API for type-safe XML parsing
#### Declarative Parsing with Converter API (Recommended)
The converter module provides a zod-style declarative API for parsing and writing XML:
`typescript
import { x } from 'stax-xml/converter';
// Define schema with XPath
const bookSchema = x.object({
title: x.string().xpath('/book/title'),
author: x.string().xpath('/book/author'),
price: x.number().xpath('/book/price'),
tags: x.string().array().xpath('/book/tags/tag')
});
// Parse XML
const xml =
;
const result = await bookSchema.parse(xml);
// Result: { title: 'TypeScript Deep Dive', author: 'John Smith', price: 29.99, tags: ['programming', 'typescript'] }
// Write XML back
const newXml = await bookSchema.write(result, { rootElement: 'book' });
`
Key features of the Converter API:
- Type-safe parsing: Infer TypeScript types from schemas
- XPath support: Use XPath expressions for element selection
- Bidirectional: Parse XML โ Object and Object โ XML
- Composable: Build complex schemas from simple primitives
- Optional values: Handle missing elements gracefully with .optional()
- Transformations: Apply custom transformations with .transform()
#### Event-based Parsing (Low-level API)
##### Basic Asynchronous Parsing (StaxXmlParser)
`typescript
import { StaxXmlParser, XmlEventType } from 'stax-xml';
const xmlContent = '- Hello
';
const stream = new ReadableStream({
start(controller) {
controller.enqueue(new TextEncoder().encode(xmlContent));
controller.close();
}
});
async function parseXml() {
const parser = new StaxXmlParser(stream);
for await (const event of parser) {
console.log(event);
}
}
parseXml();
`
##### Basic Synchronous Parsing (StaxXmlParserSync)
`typescript
import { StaxXmlParserSync, XmlEventType } from 'stax-xml';
const xmlContent = '123 ';
const parser = new StaxXmlParserSync(xmlContent);
for (const event of parser) {
console.log(event);
}
`
For detailed API documentation:
- Converter API Guide: Declarative parsing with schemas
- StaxXmlParser (Asynchronous): Event-based parsing from streams
- StaxXmlParserSync (Synchronous): Event-based parsing from strings
$3
StAX-XML uses only Web Standard APIs, making it compatible with:
- Node.js (v18+)
- Bun (any version)
- Deno (any version)
- Web Browsers (modern browsers)
- Edge Runtime (Vercel, Cloudflare Workers, etc.)
$3
`bash
bun test
`
#### Benchmark Results
Disclaimer: These benchmarks were performed on a specific system (cpu: 13th Gen Intel(R) Core(TM) i5-13600K, runtime: node 22.17.0 (x64-win32)) and may vary on different hardware and environments.
large.xml (97MB) parsing
| Benchmark | avg (min โฆ max) | p75 / p99 | Memory (avg) |
| :------------------ | :-------------- | :-------------- | :----------- |
| stax-xml to object | 4.36 s/iter | 4.42 s | 2.66 mb |
| stax-xml consume | 3.61 s/iter | 3.65 s | 3.13 mb |
| xml2js | 6.00 s/iter | 6.00 s | 1.80 mb |
| fast-xml-parser | 4.25 s/iter | 4.26 s | 151.81 mb |
| txml | 1.05 s/iter | 1.06 s | 179.81 mb |
midsize.xml (13MB) parsing
| Benchmark | avg (min โฆ max) | p75 / p99 | Memory (avg) |
| :------------------ | :-------------- | :-------------- | :----------- |
| stax-xml to object | 492.06 ms/iter | 493.28 ms | 326.28 kb |
| stax-xml consume | 469.66 ms/iter | 471.54 ms | 174.51 kb |
| xml2js | 163.26 ยตs/iter | 161.20 ยตs | 89.89 kb |
| fast-xml-parser | 529.99 ms/iter | 531.12 ms | 1.92 mb |
| txml | 112.81 ms/iter | 113.26 ms | 1.00 mb |
complex.xml (2KB) parsing
| Benchmark | avg (min โฆ max) | p75 / p99 | Memory (avg) |
| :------------------ | :-------------- | :-------------- | :----------- |
| stax-xml to object | 85.79 ยตs/iter | 75.60 ยตs | 105.11 kb |
| stax-xml consume | 50.38 ยตs/iter | 49.43 ยตs | 271.12 b |
| xml2js | 147.45 ยตs/iter | 153.50 ยตs | 89.42 kb |
| fast-xml-parser | 101.11 ยตs/iter | 102.20 ยตs | 92.92 kb |
| txml | 9.40 ยตs/iter | 9.41 ยตs | 125.89 b |
books.xml (4KB) parsing
| Benchmark | avg (min โฆ max) | p75 / p99 | Memory (avg) |
| :------------------ | :-------------- | :-------------- | :----------- |
| stax-xml to object | 166.73 ยตs/iter | 156.20 ยตs | 221.40 kb |
| stax-xml consume | 176.45 ยตs/iter | 151.70 ยตs | 202.08 kb |
| xml2js | 259.90 ยตs/iter | 254.50 ยตs | 161.25 kb |
| fast-xml-parser | 239.57 ยตs/iter | 203.30 ยตs | 226.17 kb |
| txml | 19.18 ยตs/iter | 19.26 ยตs | 303.13 b |
$3
Sources of sample XML files used in testing:
- books.xml: Microsoft XML Document Examples)
- simple-namespace.xml: W3Schools XML Namespaces Guide
- treebank_e.xml: University of Washington XML Data Repository
$3
MIT
$3
Contributions are welcome! Please feel free to submit a Pull Request.
---
Korean
Java์ StAX(Streaming API for XML)์์ ์๊ฐ์ ๋ฐ์ ๊ณ ์ฑ๋ฅ pull ๋ฐฉ์์ JavaScript/TypeScript XML ํ์์
๋๋ค. ๋์ฉ๋ ํ์ผ์ ์ํ ์์ ๋น๋๊ธฐ ์คํธ๋ฆผ ๊ธฐ๋ฐ ํ์ฑ๊ณผ ์์ ์ธ๋ฉ๋ชจ๋ฆฌ XML ๋ฌธ์๋ฅผ ์ํ ๋๊ธฐ ํ์ฑ์ ๋ชจ๋ ์ ๊ณตํฉ๋๋ค. ๊ธฐ์กด์ XML-JSON ๋งคํผ์ ๋ฌ๋ฆฌ, StAX-XML์ ์ฌ์ฉํ๋ฉด XML ๋ฐ์ดํฐ๋ฅผ ์ํ๋ ์์์ ๊ตฌ์กฐ๋ก ๋งคํํ ์ ์์ผ๋ฉฐ, ์คํธ๋ฆฌ๋ฐ ๋๋ ์ง์ ๋ฌธ์์ด ์ฒ๋ฆฌ๋ฅผ ํตํด XML ํ์ผ์ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
$3
- ์ ์ธ์ Converter API: ํ์
์์ ํ XML ํ์ฑ๊ณผ ์ฐ๊ธฐ๋ฅผ ์ํ Zod ์คํ์ผ ์คํค๋ง API
- XPath ์ง์: ์ ์ฐํ ์์ ์ ํ์ ์ํ XPath ํํ์ ์ฌ์ฉ
- ์๋ฐฉํฅ ๋ณํ: XML์ ๊ฐ์ฒด๋ก ํ์ฑํ๊ณ ๊ฐ์ฒด๋ฅผ ๋ค์ XML๋ก ์์ฑ
- ์์ ๋น๋๊ธฐ (์คํธ๋ฆผ ๊ธฐ๋ฐ): ๋์ฉ๋ XML ํ์ผ์ ๋ฉ๋ชจ๋ฆฌ ํจ์จ์ ์ฒ๋ฆฌ
- ๋๊ธฐ (๋ฌธ์์ด ๊ธฐ๋ฐ): ์์ ์ธ๋ฉ๋ชจ๋ฆฌ XML ๋ฌธ์์ด์ ๊ณ ์ฑ๋ฅ ํ์ฑ
- ์ฌ์ฉ์ ์ ์ ๋งคํ: ๋จ์ํ JSON ๊ฐ์ฒด๊ฐ ์๋ ์ํ๋ ๊ตฌ์กฐ๋ก XML ๋ฐ์ดํฐ ๋งคํ ๊ฐ๋ฅ
- ๊ณ ์ฑ๋ฅ: ์๋์ ๋ฎ์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ ์ต์ ํ
- ๋ฒ์ฉ ํธํ์ฑ: ์น ํ์ค API๋ง ์ฌ์ฉํ์ฌ Node.js, Bun, Deno, ์น ๋ธ๋ผ์ฐ์ ์์ ๋ชจ๋ ๋์
- ๋ค์์คํ์ด์ค ์ง์: ๊ธฐ๋ณธ XML ๋ค์์คํ์ด์ค ์ฒ๋ฆฌ
- ์ํฐํฐ ์ง์: ์ฌ์ฉ์ ์ ์ ์ํฐํฐ ์ง์์ ํฌํจํ ๋ด์ฅ ์ํฐํฐ ๋์ฝ๋ฉ
- TypeScript ์ง์: ํฌ๊ด์ ์ธ ํ์
์ ์๋ก ์์ ํ TypeScript ์ง์
$3
`bash
npm
npm install stax-xml
yarn
yarn add stax-xml
pnpm
pnpm add stax-xml
bun
bun add stax-xml
deno
deno add npm:stax-xml
`
$3
์์ธํ ์ฌ์ฉ๋ฒ, API ์ฐธ์กฐ, ํํ ๋ฆฌ์ผ์ ๊ณต์ ๋ฌธ์๋ฅผ ์ฐธ์กฐํ์ธ์.
$3
StAX-XML์ ๋ ๊ฐ์ง ํ์ฑ ๋ฐฉ์์ ์ ๊ณตํฉ๋๋ค:
1. ์ด๋ฒคํธ ๊ธฐ๋ฐ API: ์ธ๋ฐํ ์ ์ด๋ฅผ ์ํ ์ ์์ค ์คํธ๋ฆฌ๋ฐ ํ์
2. Converter API: ํ์
์์ ํ XML ํ์ฑ์ ์ํ ์ ์ธ์ Zod ์คํ์ผ ์คํค๋ง API
#### Converter API๋ฅผ ์ฌ์ฉํ ์ ์ธ์ ํ์ฑ (๊ถ์ฅ)
Converter ๋ชจ๋์ XML ํ์ฑ ๋ฐ ์ฐ๊ธฐ๋ฅผ ์ํ Zod ์คํ์ผ์ ์ ์ธ์ API๋ฅผ ์ ๊ณตํฉ๋๋ค:
`typescript
import { x } from 'stax-xml/converter';
// XPath๋ฅผ ์ฌ์ฉํ ์คํค๋ง ์ ์
const bookSchema = x.object({
title: x.string().xpath('/book/title'),
author: x.string().xpath('/book/author'),
price: x.number().xpath('/book/price'),
tags: x.string().array().xpath('/book/tags/tag')
});
// XML ํ์ฑ
const xml =
;
const result = await bookSchema.parse(xml);
// ๊ฒฐ๊ณผ: { title: 'TypeScript ๋ฅ๋ค์ด๋ธ', author: 'ํ๊ธธ๋', price: 29.99, tags: ['ํ๋ก๊ทธ๋๋ฐ', 'ํ์
์คํฌ๋ฆฝํธ'] }
// XML๋ก ๋ค์ ์ฐ๊ธฐ
const newXml = await bookSchema.write(result, { rootElement: 'book' });
`
Converter API์ ์ฃผ์ ๊ธฐ๋ฅ:
- ํ์
์์ ํ์ฑ: ์คํค๋ง์์ TypeScript ํ์
์๋ ์ถ๋ก
- XPath ์ง์: ์์ ์ ํ์ ์ํ XPath ํํ์ ์ฌ์ฉ
- ์๋ฐฉํฅ: XML โ ๊ฐ์ฒด, ๊ฐ์ฒด โ XML ๋ณํ
- ์กฐํฉ ๊ฐ๋ฅ: ๋จ์ ๊ธฐ๋ณธํ์์ ๋ณต์กํ ์คํค๋ง ๊ตฌ์ถ
- ์ ํ์ ๊ฐ: .optional()๋ก ๋๋ฝ๋ ์์ ์ฐ์ํ๊ฒ ์ฒ๋ฆฌ
- ๋ณํ: .transform()์ผ๋ก ์ฌ์ฉ์ ์ ์ ๋ณํ ์ ์ฉ
#### ์ด๋ฒคํธ ๊ธฐ๋ฐ ํ์ฑ (์ ์์ค API)
##### ๊ธฐ๋ณธ ๋น๋๊ธฐ ํ์ฑ (StaxXmlParser)
`typescript
import { StaxXmlParser, XmlEventType } from 'stax-xml';
const xmlContent = '- ์๋
ํ์ธ์
';
const stream = new ReadableStream({
start(controller) {
controller.enqueue(new TextEncoder().encode(xmlContent));
controller.close();
}
});
async function parseXml() {
const parser = new StaxXmlParser(stream);
for await (const event of parser) {
console.log(event);
}
}
parseXml();
`
##### ๊ธฐ๋ณธ ๋๊ธฐ ํ์ฑ (StaxXmlParserSync)
`typescript
import { StaxXmlParserSync, XmlEventType } from 'stax-xml';
const xmlContent = '123 ';
const parser = new StaxXmlParserSync(xmlContent);
for (const event of parser) {
console.log(event);
}
`
์์ธํ API ๋ฌธ์๋ ๋ค์์ ์ฐธ์กฐํ์ธ์:
- Converter API ๊ฐ์ด๋: ์คํค๋ง๋ฅผ ์ฌ์ฉํ ์ ์ธ์ ํ์ฑ
- StaxXmlParser (๋น๋๊ธฐ): ์คํธ๋ฆผ ๊ธฐ๋ฐ ์ด๋ฒคํธ ํ์ฑ
- StaxXmlParserSync (๋๊ธฐ): ๋ฌธ์์ด ๊ธฐ๋ฐ ์ด๋ฒคํธ ํ์ฑ
$3
StAX-XML์ ์น ํ์ค API๋ง์ ์ฌ์ฉํ์ฌ ๋ค์ ํ๊ฒฝ์์ ๋์ํฉ๋๋ค:
- Node.js (v18+)
- Bun (๋ชจ๋ ๋ฒ์ )
- Deno (๋ชจ๋ ๋ฒ์ )
- ์น ๋ธ๋ผ์ฐ์ (์ต์ ๋ธ๋ผ์ฐ์ )
- Edge Runtime (Vercel, Cloudflare Workers ๋ฑ)
$3
ํ
์คํธ์ ์ฌ์ฉ๋ ์ํ ํ์ผ๋ค์ ์ถ์ฒ:
XML ํ์ผ:
- books.xml: Microsoft XML ๋ฌธ์ ์์ )
- simple-namespace.xml: W3Schools XML ๋ค์์คํ์ด์ค ๊ฐ์ด๋
- treebank_e.xml`: University of Washington XML Data Repository