npm install @nodable/flexible-xml-parser @nodable/compact-builderInstall additional output builders only as needed:
npm install @nodable/node-tree-builder
npm install @nodable/sequential-builderimport XMLParser from '@nodable/flexible-xml-parser';
const parser = new XMLParser();
const result = parser.parse(`
<books>
<book id="1">
<title>The Great Gatsby</title>
<year>1925</year>
<price>10.99</price>
</book>
</books>
`);
// { books: { book: { year: 1925, price: 10.99, title: 'The Great Gatsby' } } }Numbers and booleans are automatically coerced. To include attributes, disable the default skip:
const parser = new XMLParser({ skip: { attributes: false } });
parser.parse('<book id="1"><title>1984</title></book>');
// { book: { '@_id': 1, title: '1984' } }const parser = new XMLParser();
const config = parser.parse(xmlString);
console.log(config.config.database.host); // 'localhost'
console.log(config.config.database.port); // 5432 (number)
console.log(config.config.cache.enabled); // true (boolean)const parser = new XMLParser({ skip: { attributes: false } });
const feed = parser.parse(rssFeedXml);
for (const item of feed.rss.channel.item) {
console.log(item.title, item.link);
}import { CompactBuilderFactory } from '@nodable/compact-builder';
const builder = new CompactBuilderFactory({
tags: { valueParsers: [] },
attributes: { valueParsers: [] },
});
const parser = new XMLParser({ OutputBuilder: builder });
// All values come out as strings — no type coercionimport { CompactBuilderFactory } from '@nodable/compact-builder';
import { NumberValueParser } from '@nodable/base-output-builder';
const builder = new CompactBuilderFactory({
tags: {
valueParsers: ['entity', new NumberValueParser({ leadingZeros: false }), 'boolean'],
},
});
const parser = new XMLParser({ OutputBuilder: builder });
parser.parse('<item><sku>00123</sku><price>9.99</price></item>');
// { item: { sku: '00123', price: 9.99 } }const parser = new XMLParser({ skip: { nsPrefix: true, attributes: false } });
parser.parse('<soap:Envelope><soap:Body><m:Item>Apple</m:Item></soap:Body></soap:Envelope>');
// { Envelope: { Body: { Item: 'Apple' } } }const parser = new XMLParser({
limits: { maxNestedTags: 50, maxAttributesPerTag: 20 },
doctypeOptions: { enabled: false },
});
try {
const result = parser.parse(untrustedXml);
} catch (e) {
if (e instanceof ParseError) {
console.error(e.code, e.message);
}
}// Option 1 (default): CDATA merged into text
const parser1 = new XMLParser();
parser1.parse('<html><![CDATA[<div>content</div>]]></html>');
// { html: '<div>content</div>' }
// Option 2: separate CDATA key
const parser2 = new XMLParser({ nameFor: { cdata: '#cdata' } });
parser2.parse('<html><![CDATA[<div>content</div>]]></html>');
// { html: { '#cdata': '<div>content</div>' } }new XMLParser({
skip: { attributes: false }, // parse attributes
nameFor: { cdata: '#cdata' }, // separate CDATA key
attributes:{ prefix: '@_' }, // attribute key prefix
tags: { unpaired: ['br', 'img'] }, // void/self-closing HTML tags
limits: { maxNestedTags: 100 }, // DoS guard
});➡ Next: 02 — Options Reference