Lightweight XML to JSON parser with zero dependencies. Works in browser, Node.js, and Deno.
Designed for parsing XML APIs (WebDAV PROPFIND, S3 ListBucket, etc.) in environments where DOMParser is unavailable — such as service workers.
import{parseXml}from"@violentmonkey/xml-parser";const{ node, warnings }=parseXml(`<?xml version="1.0"?><D:multistatus xmlns:D="DAV:"> <D:response> <D:href>/file.txt</D:href> <D:propstat> <D:prop> <D:displayname>file.txt</D:displayname> <D:getcontentlength>1234</D:getcontentlength> </D:prop> <D:status>HTTP/1.1 200 OK</D:status> </D:propstat> </D:response></D:multistatus>`);// node.multistatus.response.href → "/file.txt"// node.multistatus.response.propstat.prop.displayname → "file.txt"// node.multistatus.response.propstat.prop.getcontentlength → 1234 (number)Parameters:
input(string) — XML text to parse.options(optional):ignoreAttributes(boolean) — Skip all attributes. Defaultfalse.removeNSPrefix(boolean) — Strip namespace prefixes from element names. Defaulttrue.
Returns:{ node: Record<string, XmlValue>, warnings: Warning[] }
typeXmlValue=string|number|{[key: string]: XmlValue}|XmlValue[];| Feature | Description |
|---|---|
| Namespace handling | Strips D: → D:response becomes response by default. Opt out with removeNSPrefix: false. |
| Attributes | Prefixed with @, e.g. <item id="42"> → { "@id": "42" }. xmlns* attributes are skipped. |
| Text vs object | Text-only elements return string/number; elements with children return object. |
| Arrays | Repeated sibling elements are automatically wrapped in an array. |
| Numbers | Numeric strings like "1234" are parsed as numbers. |
| CDATA | CDATA sections are treated as text content. |
| Warnings | Non-fatal issues (e.g. duplicate attributes) are returned in warnings array. |
| Zero dependencies | ~250 lines of pure TypeScript. |
MIT