{"id":11982,"library":"saxes","title":"Saxes Streaming XML Parser","description":"Saxes is an evented, streaming XML parser for JavaScript, currently at version 6.0.0. It is a modern, stricter, and significantly faster fork of the original `sax` library, designed primarily for Node.js environments (requiring Node.js >=12.22.7) but also functional in browsers. Its core differentiator is a strong adherence to XML 1.0/1.1 and Namespaces in XML 1.0/1.1 well-formedness rules, unlike `sax` which tolerates malformed structures. This makes `saxes` unsuitable for HTML or pseudo-XML parsing, as it will explicitly report well-formedness errors. While it is a non-validating parser, it aims to catch all malformed constructs outside of thorough DTD validation. `saxes` does not include a `Stream` API, a notable departure from its `sax` predecessor, and its `onerror` handler defaults to throwing errors, which can be overridden. The project is actively maintained, with a focus on performance and strict conformance to XML specifications.","status":"active","version":"6.0.0","language":"javascript","source_language":"en","source_url":"https://github.com/lddubeau/saxes","tags":["javascript","typescript"],"install":[{"cmd":"npm install saxes","lang":"bash","label":"npm"},{"cmd":"yarn add saxes","lang":"bash","label":"yarn"},{"cmd":"pnpm add saxes","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"SaxesParser is a named export. While the README example uses require('./lib/saxes'), the standard npm import path is 'saxes'.","wrong":"import SaxesParser from 'saxes';\n// OR\nconst SaxesParser = require('saxes').SaxesParser;","symbol":"SaxesParser","correct":"import { SaxesParser } from 'saxes';"},{"note":"SaxesOptions is a type export. Use `import type` for clarity and to prevent runtime issues in some bundlers or environments without proper type stripping.","wrong":"import { SaxesOptions } from 'saxes';","symbol":"SaxesOptions","correct":"import type { SaxesOptions } from 'saxes';"},{"note":"While `saxes.SaxesParser` works, direct destructuring is often preferred for named exports in CommonJS modules, aligning with modern JavaScript practices. The original README uses a local path which is uncommon for npm packages.","wrong":"const saxes = require('saxes');\nconst parser = new saxes.SaxesParser();","symbol":"CommonJS require","correct":"const { SaxesParser } = require('saxes');"}],"quickstart":{"code":"import { SaxesParser } from 'saxes';\n\nconst xmlString = `<root>\n  <item id=\"1\">Hello &amp; World!</item>\n  <item id=\"2\"><![CDATA[<tag>content</tag>]]></item>\n</root>`;\n\nconst parser = new SaxesParser();\n\nparser.on('error', (err) => {\n  console.error('XML Parsing Error:', err.message);\n  // The default onerror handler throws, so subsequent data calls might not happen if not caught.\n});\n\nparser.on('opentag', (node) => {\n  console.log(`Opened tag: ${node.name} with attributes:`, node.attributes);\n});\n\nparser.on('text', (text) => {\n  if (text.trim().length > 0) {\n    console.log(`Text content: '${text.trim()}'`);\n  }\n});\n\nparser.on('closetag', (nodeName) => {\n  console.log(`Closed tag: ${nodeName}`);\n});\n\nparser.on('end', () => {\n  console.log('Finished parsing XML.');\n});\n\ntry {\n  parser.write(xmlString).close();\n} catch (e) {\n  // Catch errors if the default onerror handler is active and throws\n  console.error('Caught error during write/close:', e.message);\n}","lang":"typescript","description":"Demonstrates basic parsing of an XML string, handling open tags, text content, close tags, and errors using event listeners. It shows both attributes and CDATA sections."},"warnings":[{"fix":"Ensure all input XML strictly adheres to XML 1.0/1.1 and Namespaces specifications. Do not feed HTML or pseudo-XML to saxes.","message":"Saxes is significantly stricter with XML well-formedness than its predecessor, `sax`. It will report errors for malformed XML that `sax` might silently accept. This is a deliberate design choice for compliance.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Replace `Stream` usage with direct calls to `parser.write(chunk)` and `parser.close()` for input termination.","message":"Saxes does not expose a `Stream` API. If you were relying on `sax`'s `Stream` functionality, you will need to adapt your code to use the `parser.write()` method directly with character chunks.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Implement a custom `parser.on('error', handlerFunction)` to catch and handle parsing errors gracefully. If your handler does nothing, there is no `resume` method to call.","message":"The `onerror` handler in `saxes` throws errors by default. In `sax`, errors would often be emitted and require explicit `parser.error = null` and `parser.resume()` calls. This behavior change means unhandled errors will halt execution.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"For DTD-defined entities, you must manually listen to the `doctype` event, fetch the DTD content, parse it, and add custom entities to `parser.ENTITIES` if you require their resolution.","message":"Saxes is a non-validating parser. It does not thoroughly parse DTDs, meaning most malformedness errors within DTDs cannot be reported. Basic XML entities (`&amp;`, `&lt;`, etc.) are handled, but custom DTD-defined entities are not automatically processed.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Ensure your runtime environment meets the minimum Node.js requirement of v12.22.7 or a modern browser environment. Transpilation to ES5 is not supported in the default build.","message":"Saxes dropped support for antiquated platforms, including Node versions older than 10 and IE11. The library is built with modern JavaScript (ES6+).","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Rely strictly on the documented public API. Consult the JSDOC comments in the source code for the definitive public interface.","message":"The internal implementation and non-public API of `saxes` are subject to change without warning. The documentation explicitly advises against using anything not formally public, protected, or documented in JSDOC as public.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Review your XML input for any structural errors, unclosed tags, invalid characters, or incorrect entity usage. Ensure it's valid XML, not HTML.","cause":"The input XML string is not well-formed according to XML 1.0/1.1 specifications. Saxes is very strict and will reject documents that `sax` might parse.","error":"XML Parsing Error: Malformed XML: unexpected end of document"},{"fix":"For ES Modules: `import { SaxesParser } from 'saxes';`. For CommonJS: `const { SaxesParser } = require('saxes');`.","cause":"Incorrect import statement, often due to mixing CommonJS `require` with ES Module `import` syntax or attempting a default import when `SaxesParser` is a named export.","error":"TypeError: SaxesParser is not a constructor"},{"fix":"Handle errors in your `parser.on('error', ...)` listener. Saxes throws errors by default; if you catch them, you typically just let the parser continue or stop processing the input, as there's no `resume` mechanism.","cause":"Attempting to call `parser.resume()` after an error, a method that existed in the original `sax` library but is not present in `saxes` due to the removal of the `Stream` API and different error handling philosophy.","error":"TypeError: parser.resume is not a function"}],"ecosystem":"npm"}