{"id":13492812,"url":"https://github.com/rgrove/parse-xml","last_synced_at":"2025-05-15T01:09:58.861Z","repository":{"id":43598728,"uuid":"93292369","full_name":"rgrove/parse-xml","owner":"rgrove","description":"A fast, safe, compliant XML parser for Node.js and browsers.","archived":false,"fork":false,"pushed_at":"2024-10-26T04:12:31.000Z","size":1648,"stargazers_count":307,"open_issues_count":1,"forks_count":16,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-04-13T23:53:48.938Z","etag":null,"topics":["javascript","js","node","nodejs","parse-xml","parser","parsing","typescript","xml","xml-parser","xml-parsing"],"latest_commit_sha":null,"homepage":"https://rgrove.github.io/parse-xml","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rgrove.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-06-04T05:27:39.000Z","updated_at":"2025-04-11T18:52:43.000Z","dependencies_parsed_at":"2024-06-18T12:41:31.211Z","dependency_job_id":"741668c4-7e78-4f3b-bfc9-bbade3fd7bd9","html_url":"https://github.com/rgrove/parse-xml","commit_stats":{"total_commits":175,"total_committers":6,"mean_commits":"29.166666666666668","dds":0.03428571428571425,"last_synced_commit":"3b1000032a2d26631e738583fb1a82cc83c64461"},"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rgrove%2Fparse-xml","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rgrove%2Fparse-xml/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rgrove%2Fparse-xml/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rgrove%2Fparse-xml/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rgrove","download_url":"https://codeload.github.com/rgrove/parse-xml/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254254043,"owners_count":22039792,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript","js","node","nodejs","parse-xml","parser","parsing","typescript","xml","xml-parser","xml-parsing"],"created_at":"2024-07-31T19:01:09.438Z","updated_at":"2025-05-15T01:09:53.845Z","avatar_url":"https://github.com/rgrove.png","language":"JavaScript","readme":"# parse-xml\n\nA fast, safe, compliant XML parser for Node.js and browsers.\n\n[![npm version](https://img.shields.io/npm/v/%40rgrove%2Fparse-xml)](https://www.npmjs.com/package/@rgrove/parse-xml) [![Bundle size](https://badgen.net/bundlephobia/minzip/@rgrove/parse-xml)](https://bundlephobia.com/result?p=@rgrove/parse-xml) [![CI](https://github.com/rgrove/parse-xml/actions/workflows/ci.yml/badge.svg)](https://github.com/rgrove/parse-xml/actions/workflows/ci.yml)\n\n## Links\n\n- [API Docs](https://rgrove.github.io/parse-xml/)\n- [GitHub](https://github.com/rgrove/parse-xml)\n- [npm](https://www.npmjs.com/package/@rgrove/parse-xml)\n\n## Installation\n\n```\nnpm install @rgrove/parse-xml\n```\n\nOr, if you like living dangerously, you can load [the minified bundle](https://unpkg.com/@rgrove/parse-xml/dist/global.min.js) in a browser via [Unpkg](https://unpkg.com/) and use the `parseXml` global.\n\n## Features\n\n-   Returns a convenient [object tree](#basic-usage) representing an XML document.\n\n-   Works great in Node.js and browsers.\n\n-   Provides [helpful, detailed error messages](#friendly-errors) with context when a document is not well-formed.\n\n-   Mostly conforms to [XML 1.0 (Fifth Edition)](https://www.w3.org/TR/2008/REC-xml-20081126/) as a non-validating parser (see [below](#not-features) for details).\n\n-   Passes all relevant tests in the [XML Conformance Test Suite](https://www.w3.org/XML/Test/).\n\n-   Written in TypeScript and compiled to ES2020 JavaScript for Node.js and ES2017 JavaScript for browsers. The browser build is also optimized for minification.\n\n-   Extremely [fast](#benchmark) and surprisingly [small](https://bundlephobia.com/result?p=@rgrove/parse-xml).\n\n-   Zero dependencies.\n\n## Not Features\n\nWhile this parser is capable of parsing document type declarations (`\u003c!DOCTYPE ... \u003e`) and including them in the node tree, it doesn't actually do anything with them. External document type definitions won't be loaded, and the parser won't validate the document against a DTD or resolve custom entity references defined in a DTD.\n\nIn addition, the only supported character encoding is UTF-8 because it's not feasible (or useful) to support other character encodings in JavaScript.\n\n## Examples\n\n### Basic Usage\n\n**ESM**\n\n```js\nimport { parseXml } from '@rgrove/parse-xml';\nparseXml('\u003ckittens fuzzy=\"yes\"\u003eI like fuzzy kittens.\u003c/kittens\u003e');\n```\n\n**CommonJS**\n\n```js\nconst { parseXml } = require('@rgrove/parse-xml');\nparseXml('\u003ckittens fuzzy=\"yes\"\u003eI like fuzzy kittens.\u003c/kittens\u003e');\n```\n\nThe result is an [`XmlDocument`](https://rgrove.github.io/parse-xml/classes/XmlDocument.html) instance containing the parsed document, with a structure that looks like this (some properties and methods are excluded for clarity; see the [API docs](https://rgrove.github.io/parse-xml/) for details):\n\n```js\n{\n  type: 'document',\n  children: [\n    {\n      type: 'element',\n      name: 'kittens',\n      attributes: {\n        fuzzy: 'yes'\n      },\n      children: [\n        {\n          type: 'text',\n          text: 'I like fuzzy kittens.'\n        }\n      ],\n      parent: { ... },\n      isRootNode: true\n    }\n  ]\n}\n```\n\nAll parse-xml objects have `toJSON()` methods that return JSON-serializable objects, so you can easily convert an XML document to JSON:\n\n```js\nlet json = JSON.stringify(parseXml(xml));\n```\n\n### Friendly Errors\n\nWhen something goes wrong, parse-xml throws an error that tells you exactly what happened and shows you where the problem is so you can fix it.\n\n```js\nparseXml('\u003cfoo\u003e\u003cbar\u003ebaz\u003c/foo\u003e');\n```\n\n**Output**\n\n```\nError: Missing end tag for element bar (line 1, column 14)\n  \u003cfoo\u003e\u003cbar\u003ebaz\u003c/foo\u003e\n               ^\n```\n\nIn addition to a helpful message, error objects have the following properties:\n\n-   **column** _Number_\n\n    Column where the error occurred (1-based).\n\n-   **excerpt** _String_\n\n    Excerpt from the input string that contains the problem.\n\n-   **line** _Number_\n\n    Line where the error occurred (1-based).\n\n-   **pos** _Number_\n\n    Character position where the error occurred relative to the beginning of the input (0-based).\n\n## Why another XML parser?\n\nThere are many XML parsers for Node, and some of them are good. However, most of them suffer from one or more of the following shortcomings:\n\n-   Native dependencies.\n\n-   Loose, non-standard parsing behavior that can lead to unexpected or even unsafe results when given input the author didn't anticipate.\n\n-   Kitchen sink APIs that tightly couple a parser with DOM manipulation functions, a stringifier, or other tooling that isn't directly related to parsing and consuming XML.\n\n-   Stream-based parsing. This is great in the rare case that you need to parse truly enormous documents, but can be a pain to work with when all you want is a node tree.\n\n-   Poor error handling.\n\n-   Too big or too Node-specific to work well in browsers.\n\nparse-xml's goal is to be a small, fast, safe, compliant, non-streaming, non-validating, browser-friendly parser, because I think this is an under-served niche.\n\nI think parse-xml demonstrates that it's not necessary to jettison the spec entirely or to write complex code in order to implement a small, fast XML parser.\n\nAlso, it was fun.\n\n## Benchmark\n\nHere's how parse-xml's performance stacks up against a few comparable libraries:\n\n-   [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser), which claims to be the fastest pure JavaScript XML parser\n-   [libxmljs2](https://github.com/marudor/libxmljs2), which is based on the native libxml library written in C\n-   [xmldoc](https://github.com/nfarina/xmldoc), which is based on [sax-js](https://github.com/isaacs/sax-js)\n\nWhile libxmljs2 is faster at parsing medium and large documents, its performance comes at the expense of a large C dependency, no browser support, and a [history of security vulnerabilities](https://www.cvedetails.com/vulnerability-list/vendor_id-1962/product_id-3311/Xmlsoft-Libxml2.html) in the underlying libxml2 library.\n\nIn these results, \"ops/s\" refers to operations per second. Higher is faster.\n\n```\nNode.js v22.10.0 / Darwin arm64\nApple M1 Max\n\nRunning \"Small document (291 bytes)\" suite...\nProgress: 100%\n\n  @rgrove/parse-xml 4.2.0:\n    253 082 ops/s, ±0.16%   | fastest\n\n  fast-xml-parser 4.5.0:\n    127 232 ops/s, ±0.44%   | 49.73% slower\n\n  libxmljs2 0.35.0 (native):\n    68 709 ops/s, ±2.77%    | slowest, 72.85% slower\n\n  xmldoc 1.3.0 (sax-js):\n    122 345 ops/s, ±0.15%   | 51.66% slower\n\nFinished 4 cases!\n  Fastest: @rgrove/parse-xml 4.2.0\n  Slowest: libxmljs2 0.35.0 (native)\n\nRunning \"Medium document (72081 bytes)\" suite...\nProgress: 100%\n\n  @rgrove/parse-xml 4.2.0:\n    1 350 ops/s, ±0.18%   | 29.5% slower\n\n  fast-xml-parser 4.5.0:\n    560 ops/s, ±0.48%     | slowest, 70.76% slower\n\n  libxmljs2 0.35.0 (native):\n    1 915 ops/s, ±2.64%   | fastest\n\n  xmldoc 1.3.0 (sax-js):\n    824 ops/s, ±0.20%     | 56.97% slower\n\nFinished 4 cases!\n  Fastest: libxmljs2 0.35.0 (native)\n  Slowest: fast-xml-parser 4.5.0\n\nRunning \"Large document (1162464 bytes)\" suite...\nProgress: 100%\n\n  @rgrove/parse-xml 4.2.0:\n    109 ops/s, ±0.17%   | 40.11% slower\n\n  fast-xml-parser 4.5.0:\n    48 ops/s, ±0.55%    | slowest, 73.63% slower\n\n  libxmljs2 0.35.0 (native):\n    182 ops/s, ±1.16%   | fastest\n\n  xmldoc 1.3.0 (sax-js):\n    73 ops/s, ±0.50%    | 59.89% slower\n\nFinished 4 cases!\n  Fastest: libxmljs2 0.35.0 (native)\n  Slowest: fast-xml-parser 4.5.0\n```\n\nSee the [parse-xml-benchmark](https://github.com/rgrove/parse-xml-benchmark) repo for instructions on how to run this benchmark yourself.\n\n## License\n\n[ISC License](LICENSE)\n","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frgrove%2Fparse-xml","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frgrove%2Fparse-xml","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frgrove%2Fparse-xml/lists"}