### 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('' + node.name + ' ' + node.body + '?>')
}
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() + '' + tagName + '>')
}
parser.write(xmlString).close()
return output.join('\n')
}
// Usage
var messyXml = '- Product A19.99
- Product 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.