### Basic Usage Source: https://github.com/isaacs/sax-js/blob/main/README.md Demonstrates how to use the SAX parser with event handlers for text, tags, attributes, and end of document. ```APIDOC ## Basic Usage ### Description This snippet shows the fundamental way to use the SAX parser by instantiating it, defining event handlers, and writing XML data to it. ### Method `sax.parser(strict, [options])` ### Parameters #### Arguments - **strict** (Boolean) - Whether or not to be a "jerk" (strict mode). Default: `false`. - **opt** (Object) - An object bag of settings regarding string formatting. All default to `false`. - **trim** (Boolean) - Whether or not to trim text and comment nodes. - **normalize** (Boolean) - If true, then turn any whitespace into a single space. - **lowercase** (Boolean) - If true, then lowercase tag names and attribute names in loose mode, rather than uppercasing them. - **xmlns** (Boolean) - If true, then namespaces are supported. - **position** (Boolean) - If false, then don't track line/col/position. - **strictEntities** (Boolean) - If true, only parse predefined XML entities (`&`, `'`, `>`, `<`, and `"`). - **unquotedAttributeValues** (Boolean) - If true, then unquoted attribute values are allowed. Defaults to `false` when `strict` is true, `true` otherwise. ### Event Handlers - **onerror**: Function - Called when an error occurs during parsing. - **ontext**: Function(text) - Called when text content is encountered. `text` is the string of text. - **onopentag**: Function(node) - Called when an opening tag is encountered. `node` has `name` and `attributes` properties. - **onattribute**: Function(attr) - Called for each attribute. `attr` has `name` and `value` properties. - **onend**: Function - Called when the parser stream is done. ### Request Example ```javascript var sax = require('./lib/sax'), strict = true, // set to false for html-mode parser = sax.parser(strict) parser.onerror = function (e) { // an error happened. } parser.ontext = function (t) { // got some text. t is the string of text. } parser.onopentag = function (node) { // opened a tag. node has "name" and "attributes" } parser.onattribute = function (attr) { // an attribute. attr has "name" and "value" } parser.onend = function () { // parser stream is done, and ready to have more stuff written to it. } parser.write('Hello, world!').close() ``` ``` -------------------------------- ### Basic SAX Parser Usage Source: https://github.com/isaacs/sax-js/blob/main/README.md Instantiate a SAX parser, define event handlers for text, tags, attributes, and errors, then write XML data to the parser. Use strict mode for XML or false for HTML parsing. ```javascript var sax = require('./lib/sax'), strict = true, // set to false for html-mode parser = sax.parser(strict) parser.onerror = function (e) { // an error happened. } parser.ontext = function (t) { // got some text. t is the string of text. } parser.onopentag = function (node) { // opened a tag. node has "name" and "attributes" } parser.onattribute = function (attr) { // an attribute. attr has "name" and "value" } parser.onend = function () { // parser stream is done, and ready to have more stuff written to it. } parser.write('Hello, world!').close() ``` -------------------------------- ### Create and Use SAX Parser Instance Source: https://context7.com/isaacs/sax-js/llms.txt Creates a SAX parser instance for synchronous parsing with event callbacks. Use strict mode for well-formed XML and loose mode for HTML-like content with configurable options. Assign event handlers for 'onerror', 'ontext', 'onopentag', 'onclosetag', and 'onend'. ```javascript var sax = require('sax') // Create a strict parser for well-formed XML var strictParser = sax.parser(true) // Create a loose parser for HTML-like content with options var looseParser = sax.parser(false, { trim: true, // Trim whitespace from text nodes normalize: true, // Convert whitespace sequences to single space lowercase: true, // Lowercase tag names in loose mode xmlns: true, // Enable namespace support position: true, // Track line/column positions strictEntities: true // Only parse predefined XML entities }) // Assign event handlers strictParser.onerror = function (err) { console.error('Error:', err.message) this.resume() // Continue parsing after error } strictParser.ontext = function (text) { console.log('Text:', text) } strictParser.onopentag = function (node) { console.log('Open tag:', node.name, 'Attributes:', node.attributes) } strictParser.onclosetag = function (tagName) { console.log('Close tag:', tagName) } strictParser.onend = function () { console.log('Parsing complete') } // Parse XML content strictParser.write('Hello World').close() // Output: // Open tag: root Attributes: {} // Open tag: item Attributes: { id: '1' } // Text: Hello World // Close tag: item // Close tag: root // Parsing complete ``` -------------------------------- ### SAX Stream Usage with File I/O Source: https://github.com/isaacs/sax-js/blob/main/README.md Create a SAX stream parser and pipe XML data from a readable stream (e.g., a file) to the SAX stream, and then pipe the output to a writable stream (e.g., another file). Handles errors via the 'error' event. ```javascript // stream usage // takes the same options as the parser var saxStream = require('sax').createStream(strict, options) saxStream.on('error', function (e) { // unhandled errors will throw, since this is a proper node // event emitter. console.error('error!', e) // clear the error this._parser.error = null this._parser.resume() }) saxStream.on('opentag', function (node) { // same object as above }) // pipe is supported, and it's readable/writable // same chunks coming in also go out. fs.createReadStream('file.xml') .pipe(saxStream) .pipe(fs.createWriteStream('file-copy.xml')) ``` -------------------------------- ### Stream Usage Source: https://github.com/isaacs/sax-js/blob/main/README.md Illustrates how to use SAX-JS as a stream, which is useful for processing large files or data piped from other sources. ```APIDOC ## Stream Usage ### Description This snippet demonstrates using SAX-JS as a Node.js stream, allowing for efficient processing of large XML files by piping data through it. ### Method `sax.createStream(strict, [options])` ### Parameters #### Arguments - **strict** (Boolean) - Whether or not to be a "jerk" (strict mode). Default: `false`. - **options** (Object) - Same options as the `sax.parser` function. ### Event Handlers The stream emits the same events as the parser (`error`, `opentag`, `text`, etc.). ### Request Example ```javascript var saxStream = require('sax').createStream(strict, options) saxStream.on('error', function (e) { // unhandled errors will throw, since this is a proper node // event emitter. console.error('error!', e) // clear the error this._parser.error = null this._parser.resume() }) saxStream.on('opentag', function (node) { // same object as above }) // pipe is supported, and it's readable/writable // same chunks coming in also go out. fs.createReadStream('file.xml') .pipe(saxStream) .pipe(fs.createWriteStream('file-copy.xml')) ``` ``` -------------------------------- ### Parser Methods Source: https://github.com/isaacs/sax-js/blob/main/README.md Details the methods available on the SAX parser instance for writing data and managing the parsing process. ```APIDOC ## Parser Methods ### Description These are the primary methods available on a SAX parser instance to control the data input and parsing flow. ### Methods - **`write(buffer)`** - **Description**: Writes bytes onto the stream. This can be done incrementally. - **`close()`** - **Description**: Closes the stream. No more data can be written until the `end` event is signaled after processing the current buffer. - **`resume()`** - **Description**: Resumes parsing after an error has been handled. The parser will not continue in an error state without this call. ``` -------------------------------- ### Pretty Print XML with SAX-JS Source: https://context7.com/isaacs/sax-js/llms.txt This function takes an XML string and options for indentation, then parses it using SAX to produce a formatted, indented XML string. It handles various XML elements like processing instructions, DOCTYPE, tags, text, CDATA, and comments. ```javascript var sax = require('sax') var fs = require('fs') function prettyPrint(xmlString, options) { options = options || {} var indent = options.indent || ' ' var parser = sax.parser(false, { trim: true, lowercase: true }) var output = [] var level = 0 function addIndent() { return indent.repeat(level) } function escapeXml(str) { return str .replace(/&/g, '&') .replace(//g, '>') .replace(/'/g, "'") .replace(/"/g, '"') } parser.onprocessinginstruction = function (node) { output.push('') } parser.ondoctype = function (doctype) { output.push('') } parser.onopentag = function (node) { var line = addIndent() + '<' + node.name for (var attr in node.attributes) { line += ' ' + attr + '="' + escapeXml(node.attributes[attr]) + '"' } if (node.isSelfClosing) { line += '/>' } else { line += '>' level++ } output.push(line) } parser.ontext = function (text) { if (text.trim()) { output.push(addIndent() + escapeXml(text.trim())) } } parser.oncdata = function (data) { output.push(addIndent() + '') } parser.oncomment = function (comment) { output.push(addIndent() + '') } parser.onclosetag = function (tagName) { level-- output.push(addIndent() + '') } parser.write(xmlString).close() return output.join('\n') } // Usage var messyXml = 'Product A19.99Product B29.99' console.log(prettyPrint(messyXml)) ``` -------------------------------- ### Create and Use SAX Stream Parser Source: https://context7.com/isaacs/sax-js/llms.txt Creates a streaming parser implementing the Node.js Stream interface for piping XML data. Handles parsing events like 'error', 'opentag', 'text', 'closetag', 'cdata', 'comment', and 'end' using EventEmitter style. Errors can be cleared to continue parsing. ```javascript var sax = require('sax') var fs = require('fs') // Create a streaming parser with options var saxStream = sax.createStream(false, { lowercase: true, trim: true }) // Handle parsing events using EventEmitter style saxStream.on('error', function (err) { console.error('Parse error:', err) // Clear error and continue this._parser.error = null this._parser.resume() }) saxStream.on('opentag', function (node) { console.log('Tag:', node.name) for (var attr in node.attributes) { console.log(' Attribute:', attr, '=', node.attributes[attr]) } }) saxStream.on('text', function (text) { if (text.trim()) { console.log('Text content:', text) } }) saxStream.on('closetag', function (tagName) { console.log('Closing:', tagName) }) saxStream.on('cdata', function (data) { console.log('CDATA:', data) }) saxStream.on('comment', function (comment) { console.log('Comment:', comment) }) saxStream.on('end', function () { console.log('Stream parsing complete') }) // Pipe a file through the parser fs.createReadStream('document.xml') .pipe(saxStream) .on('end', function () { console.log('File processed') }) ``` -------------------------------- ### Handle XML Events with SAX-JS Source: https://context7.com/isaacs/sax-js/llms.txt Use this to handle various XML parsing events such as processing instructions, doctypes, comments, tags, text, CDATA, and errors. Ensure the parser is initialized. ```javascript var sax = require('sax') var parser = sax.parser(false, { trim: true }) // Called when parsing is ready to begin parser.onready = function () { console.log('Parser ready') } // Processing instruction: parser.onprocessinginstruction = function (node) { console.log('Processing instruction:', node.name, 'body:', node.body) } // DOCTYPE declaration parser.ondoctype = function (doctype) { console.log('DOCTYPE:', doctype) } // XML comment parser.oncomment = function (comment) { console.log('Comment:', comment) } // Called when tag name is known but before attributes parser.onopentagstart = function (tag) { console.log('Opening tag start:', tag.name) } // Called for each attribute parser.onattribute = function (attr) { console.log('Attribute:', attr.name, '=', attr.value) } // Called when opening tag is complete with all attributes parser.onopentag = function (node) { console.log('Open tag complete:', node.name, 'attributes:', node.attributes) } // Text content parser.ontext = function (text) { console.log('Text:', text) } // CDATA section events parser.onopencdata = function () { console.log('CDATA section started') } parser.oncdata = function (data) { console.log('CDATA content:', data) } parser.onclosecdata = function () { console.log('CDATA section ended') } // Script content (non-strict mode only) parser.onscript = function (script) { console.log('Script content:', script) } // Closing tag parser.onclosetag = function (tagName) { console.log('Close tag:', tagName) } // Error handling parser.onerror = function (err) { console.error('Parse error at line', this.line, 'column', this.column) console.error('Error:', err.message) this.error = null // Clear error to continue this.resume() } // Parsing complete parser.onend = function () { console.log('Parsing finished') } var xml = '' + '' + '' + '' + 'Some text' + ']]>' + '' parser.write(xml).close() ``` -------------------------------- ### Sax-JS Namespace Support Source: https://context7.com/isaacs/sax-js/llms.txt Enable namespace support by passing `{ xmlns: true }` to the parser constructor. This provides events for namespace bindings and detailed element/attribute information including local names and URIs. ```javascript var sax = require('sax') var parser = sax.parser(true, { xmlns: true }) parser.onopennamespace = function (ns) { console.log('Namespace opened - prefix:', ns.prefix || '(default)', 'uri:', ns.uri) } parser.onclosenamespace = function (ns) { console.log('Namespace closed - prefix:', ns.prefix || '(default)', 'uri:', ns.uri) } parser.onopentag = function (node) { console.log('Element:', node.name) console.log(' Local name:', node.local) console.log(' Prefix:', node.prefix || '(none)') console.log(' Namespace URI:', node.uri || '(none)') console.log(' Is self-closing:', node.isSelfClosing) for (var attrName in node.attributes) { var attr = node.attributes[attrName] console.log(' Attribute:', attr.name) console.log(' Value:', attr.value) console.log(' Local:', attr.local) console.log(' Prefix:', attr.prefix || '(none)') console.log(' URI:', attr.uri || '(none)') } } var xml = '' + '' + '' + '' parser.write(xml).close() // Output: // Namespace opened - prefix: (default) uri: http://example.com/default // Namespace opened - prefix: custom uri: http://example.com/custom // Element: root // Local name: root // Prefix: (none) // Namespace URI: http://example.com/default // Element: child // Local name: child // Namespace URI: http://example.com/default // Attribute: attr // Value: value // Element: custom:element // Local name: element // Prefix: custom // Namespace URI: http://example.com/custom // Attribute: custom:attr // Value: namespaced-value // Prefix: custom // URI: http://example.com/custom // Namespace closed - prefix: (default) uri: http://example.com/default // Namespace closed - prefix: custom uri: http://example.com/custom ``` -------------------------------- ### Incremental XML Parsing with Sax-JS Source: https://context7.com/isaacs/sax-js/llms.txt Use the `write()` method to feed XML data incrementally to the parser. This is useful for large documents or streamed data. Ensure `close()` is called after all data is written. ```javascript var sax = require('sax') var parser = sax.parser(true) var elements = [] var currentElement = null parser.onopentag = function (node) { var element = { name: node.name, attributes: node.attributes, children: [], text: '' } if (currentElement) { currentElement.children.push(element) element.parent = currentElement } else { elements.push(element) } currentElement = element } parser.ontext = function (text) { if (currentElement) { currentElement.text += text } } parser.onclosetag = function () { if (currentElement && currentElement.parent) { currentElement = currentElement.parent } else { currentElement = null } } parser.onend = function () { console.log('Parsed elements:', JSON.stringify(elements, null, 2)) } // Write XML in chunks (simulating streaming) parser.write('') parser.write('') parser.write('') parser.write('Gambardella, Matthew') parser.write('XML Developer Guide') parser.write('44.95') parser.write('') parser.write('') parser.write('Ralls, Kim') parser.write('Midnight Rain') parser.write('5.95') parser.write('') parser.write('') parser.close() ``` -------------------------------- ### Stream Large XML Files with Backpressure Source: https://context7.com/isaacs/sax-js/llms.txt Process large XML files efficiently using the streaming interface with backpressure handling. This function reads an XML file chunk by chunk and processes specific elements using callbacks. ```javascript var sax = require('sax') var fs = require('fs') function processLargeXmlFile(filePath, itemCallback, doneCallback) { var saxStream = sax.createStream(true, { trim: true, normalize: true }) var currentItem = null var currentTag = null var itemCount = 0 saxStream.on('opentag', function (node) { if (node.name === 'item') { currentItem = { attributes: node.attributes, data: {} } } else if (currentItem) { currentTag = node.name } }) saxStream.on('text', function (text) { if (currentItem && currentTag) { currentItem.data[currentTag] = text } }) saxStream.on('closetag', function (tagName) { if (tagName === 'item' && currentItem) { itemCount++ itemCallback(currentItem, itemCount) currentItem = null } currentTag = null }) saxStream.on('error', function (err) { console.error('Parse error:', err.message) this._parser.error = null this._parser.resume() }) saxStream.on('end', function () { doneCallback(null, itemCount) }) var fileStream = fs.createReadStream(filePath, { encoding: 'utf8' }) // Handle backpressure fileStream.on('data', function (chunk) { if (!saxStream.write(chunk)) { fileStream.pause() } }) saxStream.on('drain', function () { fileStream.resume() }) fileStream.on('end', function () { saxStream.end() }) fileStream.on('error', function (err) { doneCallback(err) }) } // Usage processLargeXmlFile( 'products.xml', function (item, index) { console.log('Item', index, ':', item.data.name, '-', item.data.price) }, function (err, total) { if (err) { console.error('Error:', err) } else { console.log('Processed', total, 'items') } } ) ``` -------------------------------- ### Build DOM-like Structure from XML Source: https://context7.com/isaacs/sax-js/llms.txt Use SAX events to construct an object model representation of an XML document. This function parses an XML string and returns a hierarchical object structure. ```javascript var sax = require('sax') function parseXmlToObject(xmlString) { var parser = sax.parser(true, { trim: true, xmlns: true }) var root = null var stack = [] parser.onerror = function (err) { throw new Error('XML Parse Error: ' + err.message) } parser.onopentag = function (node) { var element = { type: 'element', name: node.local || node.name, namespace: node.uri || null, prefix: node.prefix || null, attributes: {}, children: [] } // Process attributes for (var key in node.attributes) { var attr = node.attributes[key] element.attributes[attr.local || attr.name] = attr.value } if (stack.length > 0) { stack[stack.length - 1].children.push(element) } else { root = element } stack.push(element) } parser.ontext = function (text) { if (stack.length > 0 && text.trim()) { stack[stack.length - 1].children.push({ type: 'text', value: text }) } } parser.oncdata = function (data) { if (stack.length > 0) { stack[stack.length - 1].children.push({ type: 'cdata', value: data }) } } parser.oncomment = function (comment) { if (stack.length > 0) { stack[stack.length - 1].children.push({ type: 'comment', value: comment }) } } parser.onclosetag = function () { stack.pop() } parser.write(xmlString).close() return root } // Usage var xml = '' + '' + 'The Great Gatsby' + 'F. Scott Fitzgerald' + '' + '' + '' + 'A Brief History of Time' + 'Stephen Hawking' + '' + '' var result = parseXmlToObject(xml) console.log(JSON.stringify(result, null, 2)) // Output: // { // "type": "element", // "name": "library", // "namespace": "http://example.com/library", // "attributes": {}, // "children": [ // { // "type": "element", // "name": "book", // "attributes": { "id": "1", "category": "fiction" }, // "children": [ // { "type": "element", "name": "title", "children": [{ "type": "text", "value": "The Great Gatsby" }] }, // { "type": "element", "name": "author", "children": [{ "type": "text", "value": "F. Scott Fitzgerald" }] }, // { "type": "comment", "value": " Classic American novel " } // ] // }, // ... // ] // } ``` -------------------------------- ### Parser Members Source: https://github.com/isaacs/sax-js/blob/main/README.md Lists the important members (properties) available on the SAX parser instance that provide information about the current parsing state. ```APIDOC ## Parser Members ### Description These members provide insight into the parser's current state and configuration. ### Members - **`line`** (Number) - Current line number in the XML document. - **`column`** (Number) - Current column number in the XML document. - **`position`** (Number) - Current character position in the XML document. - **`startTagPosition`** (Number) - Position where the current tag started. - **`closed`** (Boolean) - Indicates if the parser can be written to. `true` means it's closed; wait for the `ready` event to write again. - **`strict`** (Boolean) - Indicates if the parser is in strict mode. - **`opt`** (Object) - Contains the options passed into the constructor. - **`tag`** (Object) - Represents the current tag being processed. ``` -------------------------------- ### Track Parser State and Position in SAX-JS Source: https://context7.com/isaacs/sax-js/llms.txt Enable position tracking to access the parser's current line, column, and character position during parsing. Useful for debugging and error reporting. ```javascript var sax = require('sax') var parser = sax.parser(true, { position: true }) parser.onopentag = function (node) { console.log('Tag:', node.name) console.log(' Position:', this.position) console.log(' Line:', this.line) console.log(' Column:', this.column) console.log(' Tag start position:', this.startTagPosition) console.log(' Strict mode:', this.strict) console.log(' Parser closed:', this.closed) } parser.ontext = function (text) { console.log('Text at line', this.line, 'column', this.column, ':', text) } parser.onerror = function (err) { console.error('Error at position', this.position) console.error('Line:', this.line, 'Column:', this.column) console.error('Current character:', this.c) console.error('Message:', err.message) this.error = null this.resume() } var xml = '\n' + ' First\n' + ' Second\n' + '' parser.write(xml).close() ``` -------------------------------- ### Customize Entity Handling in SAX-JS Source: https://context7.com/isaacs/sax-js/llms.txt Configure strict entity mode and add custom entities to the parser's ENTITIES object. This allows for custom entity resolution and handling of numeric and named entities. ```javascript var sax = require('sax') // Create parser with strict entity mode var parser = sax.parser(true, { strictEntities: true }) // Add custom entities to the parser parser.ENTITIES['custom'] = 'Custom Entity Value' parser.ENTITIES['company'] = 'Acme Corporation' parser.ENTITIES['copy'] = '\u00A9' // Copyright symbol parser.ontext = function (text) { console.log('Resolved text:', text) } parser.onerror = function (err) { console.error('Entity error:', err.message) this.error = null this.resume() } // Built-in entities: & < > ' " // Custom entities use same syntax var xml = '' + 'Standard: & < >' + 'Numeric: © ©' + 'Custom: &custom; - &company;' + '' parser.write(xml).close() // Output: // Resolved text: Standard: & < >Numeric: © ©Custom: Custom Entity Value - Acme Corporation ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.