A pure JavaScript W3C standard-based (XML DOM Level 2 Core) DOMParser and XMLSerializer module
Standard DOM constants, MIME type definitions, namespace URIs, and utility functions for validation and type checking in XML processing applications.
Supported MIME types for XML/HTML parsing with validation utilities.
/**
* Standard MIME types supported by DOMParser
*/
const MIME_TYPE = {
/** HTML document parsing with HTML-specific behavior */
HTML: 'text/html',
/** Standard XML document parsing */
XML_APPLICATION: 'application/xml',
/** Alternative XML MIME type */
XML_TEXT: 'text/xml',
/** XHTML document with XML parsing but HTML namespace */
XML_XHTML_APPLICATION: 'application/xhtml+xml',
/** SVG document parsing */
XML_SVG_IMAGE: 'image/svg+xml'
};
/**
* Validates if a MIME type is supported by DOMParser
* @param mimeType - The MIME type string to validate
* @returns True if the MIME type is supported for parsing
*/
function isValidMimeType(mimeType: string): boolean;
/**
* Checks if MIME type indicates HTML parsing mode
* @param mimeType - The MIME type to check
* @returns True if MIME type is 'text/html'
*/
function isHTMLMimeType(mimeType: string): boolean;
/**
* Checks if MIME type should use default HTML namespace
* @param mimeType - The MIME type to check
* @returns True for 'text/html' and 'application/xhtml+xml'
*/
function hasDefaultHTMLNamespace(mimeType: string): boolean;Usage Examples:
const { MIME_TYPE, isValidMimeType, isHTMLMimeType } = require('@xmldom/xmldom');
// Validate MIME types before parsing
const userMimeType = 'application/xml';
if (isValidMimeType(userMimeType)) {
console.log('Valid MIME type for parsing');
}
// Check for HTML parsing behavior
if (isHTMLMimeType(userMimeType)) {
console.log('Will parse as HTML document');
} else {
console.log('Will parse as XML document');
}
// Use constants instead of string literals
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlString, MIME_TYPE.XML_APPLICATION);
const htmlDoc = parser.parseFromString(htmlString, MIME_TYPE.HTML);
const svgDoc = parser.parseFromString(svgString, MIME_TYPE.XML_SVG_IMAGE);Standard XML namespace URIs used in web technologies.
/**
* Standard XML namespaces used in web technologies
*/
const NAMESPACE = {
/** XHTML namespace */
HTML: 'http://www.w3.org/1999/xhtml',
/** SVG namespace */
SVG: 'http://www.w3.org/2000/svg',
/** XML namespace for xml: prefixed attributes */
XML: 'http://www.w3.org/XML/1998/namespace',
/** XMLNS namespace for namespace declarations */
XMLNS: 'http://www.w3.org/2000/xmlns/'
};Usage Examples:
const { NAMESPACE, DOMParser } = require('@xmldom/xmldom');
const parser = new DOMParser();
const doc = parser.parseFromString('<root></root>', 'text/xml');
// Create elements with standard namespaces
const htmlElement = doc.createElementNS(NAMESPACE.HTML, 'div');
const svgElement = doc.createElementNS(NAMESPACE.SVG, 'circle');
// Set namespace-aware attributes
htmlElement.setAttributeNS(NAMESPACE.XML, 'xml:lang', 'en');
svgElement.setAttributeNS(null, 'r', '50');
// Check element namespaces
if (htmlElement.namespaceURI === NAMESPACE.HTML) {
console.log('Element is in HTML namespace');
}Utility functions for object manipulation and compatibility.
/**
* Object.assign ponyfill for merging objects
* Provides Object.assign functionality in ES5 environments
* @param target - Target object to merge properties into
* @param source - Source object to copy properties from
* @returns Target object with merged properties
* @throws TypeError if target is not an object
*/
function assign<T, S>(target: T, source: S): T & S;Usage Examples:
const { assign } = require('@xmldom/xmldom');
// Merge configuration objects
const defaultOptions = {
locator: true,
normalizeLineEndings: true
};
const userOptions = {
onError: (level, msg) => console.log(`${level}: ${msg}`)
};
const mergedOptions = assign(defaultOptions, userOptions);
// Result: { locator: true, normalizeLineEndings: true, onError: function }
// Use in DOMParser construction
const parser = new DOMParser(mergedOptions);Functions for handling and normalizing text content according to XML standards.
/**
* Normalizes line endings according to XML specification
* Handles various line ending formats and Unicode newline characters
* @param input - Input string with potentially mixed line endings
* @returns String with normalized line endings (LF only)
*/
function normalizeLineEndings(input: string): string;Usage Examples:
const { normalizeLineEndings } = require('@xmldom/xmldom');
// Handle text with mixed line endings
const mixedText = 'line1\r\nline2\rline3\nline4\u2028line5\u2029line6';
const normalized = normalizeLineEndings(mixedText);
console.log(normalized); // 'line1\nline2\nline3\nline4\nline5\nline6'
// Use in custom parsing options
const parser = new DOMParser({
normalizeLineEndings: (source) => {
// Custom normalization with additional processing
const normalized = normalizeLineEndings(source);
return normalized.replace(/\t/g, ' '); // Convert tabs to spaces
}
});Standard DOM node type constants for identifying node types.
/**
* Standard DOM node type constants
*/
const NodeType = {
ELEMENT_NODE: 1,
ATTRIBUTE_NODE: 2,
TEXT_NODE: 3,
CDATA_SECTION_NODE: 4,
ENTITY_REFERENCE_NODE: 5,
ENTITY_NODE: 6,
PROCESSING_INSTRUCTION_NODE: 7,
COMMENT_NODE: 8,
DOCUMENT_NODE: 9,
DOCUMENT_TYPE_NODE: 10,
DOCUMENT_FRAGMENT_NODE: 11,
NOTATION_NODE: 12
};
// Also available as static properties on Node class
Node.ELEMENT_NODE; // 1
Node.TEXT_NODE; // 3
Node.COMMENT_NODE; // 8
// etc.Usage Examples:
const { DOMParser, Node } = require('@xmldom/xmldom');
function processNode(node) {
switch (node.nodeType) {
case Node.ELEMENT_NODE:
console.log(`Element: ${node.tagName}`);
break;
case Node.TEXT_NODE:
console.log(`Text: ${node.data}`);
break;
case Node.COMMENT_NODE:
console.log(`Comment: ${node.data}`);
break;
case Node.DOCUMENT_NODE:
console.log('Document root');
break;
default:
console.log(`Other node type: ${node.nodeType}`);
}
}
// Walk through all nodes in a document
function walkNodes(node) {
processNode(node);
if (node.childNodes) {
for (let i = 0; i < node.childNodes.length; i++) {
walkNodes(node.childNodes[i]);
}
}
}Constants for comparing relative positions of nodes in the document tree.
/**
* Constants for Node.compareDocumentPosition() return values
*/
const DocumentPosition = {
DISCONNECTED: 0x01, // Nodes are not in the same tree
PRECEDING: 0x02, // Other node precedes this node
FOLLOWING: 0x04, // Other node follows this node
CONTAINS: 0x08, // Other node contains this node
CONTAINED_BY: 0x10, // Other node is contained by this node
IMPLEMENTATION_SPECIFIC: 0x20 // Implementation-specific ordering
};
// Also available as static properties on Node class
Node.DOCUMENT_POSITION_DISCONNECTED; // 0x01
Node.DOCUMENT_POSITION_PRECEDING; // 0x02
// etc.Usage Examples:
const { DOMParser, Node } = require('@xmldom/xmldom');
const parser = new DOMParser();
const doc = parser.parseFromString('<root><a></a><b></b></root>', 'text/xml');
const nodeA = doc.getElementsByTagName('a')[0];
const nodeB = doc.getElementsByTagName('b')[0];
const position = nodeA.compareDocumentPosition(nodeB);
if (position & Node.DOCUMENT_POSITION_FOLLOWING) {
console.log('Node B follows Node A');
}
if (position & Node.DOCUMENT_POSITION_DISCONNECTED) {
console.log('Nodes are in different documents');
}Additional utility functions for validation and type checking.
/**
* Type guard functions and validation utilities
* These are primarily used internally but may be useful for applications
*/
// Example usage patterns (these represent the types of utilities available)
function isElementNode(node: Node): node is Element;
function isTextNode(node: Node): node is Text;
function isDocumentNode(node: Node): node is Document;Usage Examples:
// Custom validation functions using node types
function isElementNode(node) {
return node && node.nodeType === Node.ELEMENT_NODE;
}
function isTextNode(node) {
return node && node.nodeType === Node.TEXT_NODE;
}
function getElementChildren(parent) {
const children = [];
for (let i = 0; i < parent.childNodes.length; i++) {
const child = parent.childNodes[i];
if (isElementNode(child)) {
children.push(child);
}
}
return children;
}
function getTextContent(node) {
if (isTextNode(node)) {
return node.data;
}
let text = '';
for (let i = 0; i < node.childNodes.length; i++) {
text += getTextContent(node.childNodes[i]);
}
return text;
}Predefined error handling functions for common parsing scenarios.
/**
* Predefined error handlers for DOMParser
*/
/**
* Error handler that stops parsing on any error level (error or fatalError)
* Throws ParseError to halt parsing immediately
*/
function onErrorStopParsing(): void | never;
/**
* Error handler that stops parsing on any level including warnings
* Most restrictive error handling mode
*/
function onWarningStopParsing(): never;Usage Examples:
const {
DOMParser,
onErrorStopParsing,
onWarningStopParsing
} = require('@xmldom/xmldom');
// Strict parsing - stops on errors
const strictParser = new DOMParser({
onError: onErrorStopParsing
});
// Very strict parsing - stops on warnings too
const veryStrictParser = new DOMParser({
onError: onWarningStopParsing
});
// Custom error handling with fallback
const parser = new DOMParser({
onError: (level, message, context) => {
if (level === 'fatalError') {
onErrorStopParsing(); // Delegate to standard handler
} else {
console.warn(`XML ${level}: ${message}`);
}
}
});Using constants and utilities together in real applications:
const {
DOMParser,
XMLSerializer,
MIME_TYPE,
NAMESPACE,
Node,
isValidMimeType,
normalizeLineEndings,
assign
} = require('@xmldom/xmldom');
// Configuration-driven XML processing
function createConfiguredParser(config) {
const defaultConfig = {
locator: true,
normalizeLineEndings: normalizeLineEndings,
onError: (level, msg) => console.log(`${level}: ${msg}`)
};
const finalConfig = assign(defaultConfig, config);
return new DOMParser(finalConfig);
}
// Safe document creation with validation
function createDocument(xmlString, mimeType = MIME_TYPE.XML_APPLICATION) {
if (!isValidMimeType(mimeType)) {
throw new Error(`Unsupported MIME type: ${mimeType}`);
}
const parser = createConfiguredParser({
xmlns: {
'': NAMESPACE.HTML, // Default to HTML namespace
'svg': NAMESPACE.SVG
}
});
return parser.parseFromString(xmlString, mimeType);
}
// Node type-aware processing
function processDocument(doc) {
const serializer = new XMLSerializer();
function processNode(node) {
switch (node.nodeType) {
case Node.ELEMENT_NODE:
if (node.namespaceURI === NAMESPACE.SVG) {
console.log('Processing SVG element:', node.tagName);
}
break;
case Node.TEXT_NODE:
if (node.data.trim()) {
console.log('Text content:', node.data.trim());
}
break;
}
// Process children
for (let i = 0; i < node.childNodes.length; i++) {
processNode(node.childNodes[i]);
}
}
processNode(doc);
return serializer.serializeToString(doc);
}tessl i tessl/npm-xmldom--xmldom@0.9.0