StaxXmlWriterSync - Synchronous XML Generation
StaxXmlWriterSync - Synchronous XML Generation
Section titled “StaxXmlWriterSync - Synchronous XML Generation”StAX-XML includes a synchronous XML writer that generates XML documents programmatically by building the XML string in memory. This writer provides better performance for smaller documents and synchronous workflows.
🔧 Quick Start
Section titled “🔧 Quick Start”Writing to Local File
Section titled “Writing to Local File”import { StaxXmlWriterSync } from 'stax-xml';import { writeFileSync } from 'fs';
// For Node.js - write to a local file synchronouslyfunction createLocalXmlFile() { const writer = new StaxXmlWriterSync({ prettyPrint: true, indentString: ' ' });
// Write XML document writer.writeStartDocument('1.0', 'utf-8');
writer.writeStartElement('catalog', { attributes: { version: '1.0' } });
writer.writeStartElement('product', { attributes: { id: '001' } });
writer.writeStartElement('name'); writer.writeCharacters('Laptop Computer'); writer.writeEndElement();
writer.writeStartElement('price', { attributes: { currency: 'USD' } }); writer.writeCharacters('999.99'); writer.writeEndElement();
writer.writeEndElement(); // product writer.writeEndElement(); // catalog
writer.writeEndDocument();
// Get the final XML string and write to file writeFileSync('./output.xml', writer.getXmlString()); console.log('XML file created successfully!');}
createLocalXmlFile();
Express.js Middleware - XML Response
Section titled “Express.js Middleware - XML Response”import express from 'express';import { StaxXmlWriterSync } from 'stax-xml';
const app = express();
// Middleware to create XML responseapp.get('/api/users', (req, res) => { try { // Sample data const users = [ { id: 1, name: 'John Doe', email: 'john@example.com' }, { id: 2, name: 'Jane Smith', email: 'jane@example.com' } ];
const writer = new StaxXmlWriterSync({ prettyPrint: true, indentString: ' ' });
// Set appropriate headers res.setHeader('Content-Type', 'application/xml; charset=utf-8'); res.setHeader('Cache-Control', 'no-cache');
// Write XML writer.writeStartDocument('1.0', 'utf-8'); writer.writeStartElement('users');
for (const user of users) { writer.writeStartElement('user', { attributes: { id: user.id.toString() } });
writer.writeStartElement('name'); writer.writeCharacters(user.name); writer.writeEndElement();
writer.writeStartElement('email'); writer.writeCharacters(user.email); writer.writeEndElement();
writer.writeEndElement(); // user }
writer.writeEndElement(); // users writer.writeEndDocument();
// Send the final XML string res.send(writer.getXmlString());
} catch (error) { res.status(500).json({ error: 'Failed to generate XML' }); }});
app.listen(3000, () => { console.log('Server running on port 3000');});
Hono Framework - XML Response
Section titled “Hono Framework - XML Response”import { Hono } from 'hono';import { StaxXmlWriterSync } from 'stax-xml';
const app = new Hono();
app.get('/api/products', (c) => { // Sample product data const products = [ { id: 'P001', name: 'Smartphone', price: 699.99, category: 'Electronics' }, { id: 'P002', name: 'Headphones', price: 199.99, category: 'Electronics' }, { id: 'P003', name: 'Coffee Maker', price: 149.99, category: 'Appliances' } ];
const writer = new StaxXmlWriterSync({ prettyPrint: true, indentString: ' ' });
try { // Generate XML writer.writeStartDocument('1.0', 'utf-8'); writer.writeStartElement('products', { attributes: { count: products.length.toString(), generated: new Date().toISOString() } });
for (const product of products) { writer.writeStartElement('product', { attributes: { id: product.id, category: product.category } });
writer.writeStartElement('name'); writer.writeCharacters(product.name); writer.writeEndElement();
writer.writeStartElement('price', { attributes: { currency: 'USD' } }); writer.writeCharacters(product.price.toString()); writer.writeEndElement();
writer.writeEndElement(); // product }
writer.writeEndElement(); // products writer.writeEndDocument();
// Return the generated XML string as a Response return c.text(writer.getXmlString(), 200, { 'Content-Type': 'application/xml; charset=utf-8', 'Cache-Control': 'no-cache', });
} catch (error) { return c.text('Failed to generate XML', 500); }});
export default app;
Advanced Writer Features
Section titled “Advanced Writer Features”import { StaxXmlWriterSync } from 'stax-xml';
// Create in-memory XML with custom entities and namespacesfunction createAdvancedXml() { const writer = new StaxXmlWriterSync({ prettyPrint: true, indentString: ' ', addEntities: [ { entity: 'company', value: 'Acme Corporation' }, { entity: 'copyright', value: '© 2024' } ], autoEncodeEntities: true });
// Write XML with namespaces and custom entities writer.writeStartDocument('1.0', 'utf-8');
writer.writeStartElement('document', { prefix: 'doc', uri: 'http://example.com/document', attributes: { version: '2.0' } }); writer.writeNamespace('meta', 'http://example.com/metadata');
writer.writeStartElement('header', { prefix: 'meta' }); writer.writeStartElement('title'); writer.writeCharacters('Product Catalog'); writer.writeEndElement();
writer.writeStartElement('company'); writer.writeCharacters('&company;'); // Will be encoded automatically writer.writeEndElement(); writer.writeEndElement(); // header
writer.writeStartElement('content'); writer.writeStartElement('item', { attributes: { type: 'featured' } });
// Self-closing element writer.writeStartElement('thumbnail', { attributes: { src: 'image.jpg', alt: 'Product Image' }, selfClosing: true });
writer.writeStartElement('description'); writer.writeCData('<p>This is <b>HTML</b> content in CDATA</p>'); writer.writeEndElement();
writer.writeEndElement(); // item writer.writeEndElement(); // content writer.writeEndElement(); // document
writer.writeEndDocument();
return writer.getXmlString();}
// Usageconsole.log('Generated XML:', createAdvancedXml());
Unified WriteElementOptions API
Section titled “Unified WriteElementOptions API”StaxXmlWriterSync supports a unified API that simplifies element creation by consolidating all options into a single WriteElementOptions
object:
import { StaxXmlWriterSync, WriteElementOptions } from 'stax-xml';
function createXmlWithNewAPI() { const writer = new StaxXmlWriterSync({ prettyPrint: true });
writer.writeStartDocument();
// Basic element with attributes writer.writeStartElement('catalog', { attributes: { version: '2.0', xmlns: 'http://example.com/catalog' } });
// Element with namespace and attributes writer.writeStartElement('product', { prefix: 'cat', uri: 'http://example.com/catalog', attributes: { id: '001', featured: 'true' } });
writer.writeStartElement('name'); writer.writeCharacters('Premium Laptop'); writer.writeEndElement();
// Self-closing element with attributes writer.writeStartElement('thumbnail', { attributes: { src: 'image.jpg', alt: 'Product Image', width: '200' }, selfClosing: true // No need to call writeEndElement() });
// Simple self-closing element writer.writeStartElement('br', { selfClosing: true });
writer.writeEndElement(); // product writer.writeEndElement(); // catalog
writer.writeEndDocument(); return writer.getXmlString();}
// Output:// <?xml version="1.0" encoding="UTF-8"?>// <catalog version="2.0" xmlns="http://example.com/catalog">// <cat:product id="001" featured="true" xmlns:cat="http://example.com/catalog">// <name>Premium Laptop</name>// <thumbnail src="image.jpg" alt="Product Image" width="200"/>// <br/>// </cat:product>// </catalog>
Key Benefits of the Unified API:
- Unified Parameters: All element options (attributes, namespace, self-closing) are consolidated into a single options object
- Self-Closing Support: Set
selfClosing: true
to automatically close elements without callingwriteEndElement()
- Cleaner Syntax: More intuitive and readable code structure
- Type Safety: Full TypeScript support with comprehensive type definitions
Usage Examples:
// Simple element with attributeswriter.writeStartElement('img', { attributes: { src: 'image.jpg', alt: 'Image' }, selfClosing: true});
// Element with namespacewriter.writeStartElement('title', { prefix: 'html', uri: 'http://www.w3.org/1999/xhtml', attributes: { lang: 'en' }});
📚 API Reference
Section titled “📚 API Reference”class StaxXmlWriterSync { constructor( options?: StaxXmlWriterSyncOptions )
// Document Level Methods writeStartDocument(version?: string, encoding?: string): this writeEndDocument(): void
// Element Writing Methods writeStartElement(localName: string, options?: WriteElementOptions): this writeEndElement(): this
// Attribute and Namespace Methods writeAttribute(localName: string, value: string, prefix?: string): this writeNamespace(prefix: string, uri: string): this
// Content Writing Methods writeCharacters(text: string): this writeCData(cdata: string): this writeComment(comment: string): this writeProcessingInstruction(target: string, data?: string): this
// Utility Methods setPrettyPrint(enabled: boolean): this setIndentString(indentString: string): this isPrettyPrintEnabled(): boolean getIndentString(): string getXmlString(): string}
interface StaxXmlWriterSyncOptions { encoding?: string; // Default: 'utf-8' prettyPrint?: boolean; // Default: false indentString?: string; // Default: ' ' addEntities?: { entity: string, value: string }[]; autoEncodeEntities?: boolean; // Default: true namespaces?: NamespaceDeclaration[];}
interface XmlAttribute { localName: string; value: string; prefix?: string; uri?: string;}
interface NamespaceDeclaration { prefix?: string; uri: string;}
🚀 Key Features
Section titled “🚀 Key Features”- Synchronous Operation: Builds XML string in memory for immediate access
- High Performance: Optimized for smaller to medium-sized documents
- Pretty Printing: Configurable indentation and formatting
- Namespace Support: Full XML namespace handling with prefix management
- Entity Encoding: Automatic or custom entity encoding
- Self-Closing Elements: Built-in support for self-closing tags
- Type Safety: Complete TypeScript support with detailed type definitions
- Memory Efficient: Direct string building without streaming overhead
💡 When to Use StaxXmlWriterSync
Section titled “💡 When to Use StaxXmlWriterSync”Use StaxXmlWriterSync
when:
- You need the complete XML document in memory immediately
- Working with smaller to medium-sized XML documents
- Building XML responses for web APIs
- Generating configuration files or data exports
- Working in synchronous workflows where blocking is acceptable
- Memory usage is not a primary concern
For large documents or streaming scenarios, consider using the async StaxXmlWriter
instead.