A pure JavaScript W3C standard-based (XML DOM Level 2 Core) DOMParser and XMLSerializer module.
Complete DOM manipulation capabilities including document creation, element manipulation, attribute handling, text content management, and tree traversal following W3C DOM Level 2 Core specification.
Core document interface providing factory methods for creating DOM nodes and accessing document structure.
/**
* W3C Document interface representing an XML/HTML document
*/
interface Document extends Node {
readonly doctype: DocumentType | null;
readonly implementation: DOMImplementation;
readonly documentElement: Element | null;
documentURI?: string; // xmldom extension
createElement(tagName: string): Element;
createDocumentFragment(): DocumentFragment;
createTextNode(data: string): Text;
createComment(data: string): Comment;
createCDATASection(data: string): CDATASection;
createProcessingInstruction(target: string, data: string): ProcessingInstruction;
createAttribute(name: string): Attr;
createEntityReference(name: string): EntityReference;
getElementsByTagName(tagname: string): NodeList;
getElementsByClassName(className: string): NodeList;
importNode(importedNode: Node, deep: boolean): Node;
createElementNS(namespaceURI: string | null, qualifiedName: string): Element;
createAttributeNS(namespaceURI: string | null, qualifiedName: string): Attr;
getElementsByTagNameNS(namespaceURI: string | null, localName: string): NodeList;
getElementById(elementId: string): Element | null;
}Usage Examples:
const { DOMParser } = require('xmldom');
const parser = new DOMParser();
const doc = parser.parseFromString('<root></root>', 'text/xml');
// Create different types of nodes
const element = doc.createElement('product');
const text = doc.createTextNode('Product description');
const comment = doc.createComment('This is a comment');
const cdata = doc.createCDATASection('<script>alert("test");</script>');
const attr = doc.createAttribute('id');
attr.value = '123';
// Build document structure
element.appendChild(text);
element.setAttributeNode(attr);
doc.documentElement.appendChild(element);
doc.documentElement.appendChild(comment);
// Access document properties
console.log(doc.documentElement.tagName); // "root"
console.log(doc.implementation); // DOMImplementation instanceCore element interface providing attribute manipulation, child element access, and element-specific operations.
/**
* W3C Element interface representing XML/HTML elements
*/
interface Element extends Node {
readonly tagName: string;
getAttribute(name: string): string;
setAttribute(name: string, value: string): void;
removeAttribute(name: string): void;
getAttributeNode(name: string): Attr | null;
setAttributeNode(newAttr: Attr): Attr | null;
removeAttributeNode(oldAttr: Attr): Attr;
getElementsByTagName(name: string): NodeList;
getAttributeNS(namespaceURI: string | null, localName: string): string;
setAttributeNS(namespaceURI: string | null, qualifiedName: string, value: string): void;
removeAttributeNS(namespaceURI: string | null, localName: string): void;
getAttributeNodeNS(namespaceURI: string | null, localName: string): Attr | null;
setAttributeNodeNS(newAttr: Attr): Attr | null;
getElementsByTagNameNS(namespaceURI: string | null, localName: string): NodeList;
hasAttribute(name: string): boolean;
hasAttributeNS(namespaceURI: string | null, localName: string): boolean;
}Usage Examples:
const { DOMParser } = require('xmldom');
const parser = new DOMParser();
const doc = parser.parseFromString('<catalog></catalog>', 'text/xml');
// Create and configure element
const product = doc.createElement('product');
product.setAttribute('id', 'P001');
product.setAttribute('category', 'electronics');
product.setAttribute('price', '299.99');
// Add text content
const name = doc.createElement('name');
name.appendChild(doc.createTextNode('Laptop Computer'));
product.appendChild(name);
// Add to document
doc.documentElement.appendChild(product);
// Query and modify attributes
console.log(product.getAttribute('price')); // "299.99"
product.setAttribute('price', '279.99'); // Update price
console.log(product.hasAttribute('discount')); // false
// Work with attribute nodes
const idAttr = product.getAttributeNode('id');
console.log(idAttr.name); // "id"
console.log(idAttr.value); // "P001"
// Find child elements
const nameElements = product.getElementsByTagName('name');
console.log(nameElements.item(0).textContent); // "Laptop Computer"Core node manipulation methods for building and modifying DOM tree structure.
/**
* Base Node interface with tree manipulation methods
*/
interface Node {
readonly nodeName: string;
nodeValue: string | null;
readonly nodeType: number;
readonly parentNode: Node | null;
readonly childNodes: NodeList;
readonly firstChild: Node | null;
readonly lastChild: Node | null;
readonly previousSibling: Node | null;
readonly nextSibling: Node | null;
readonly attributes: NamedNodeMap | null;
readonly ownerDocument: Document | null;
readonly namespaceURI: string | null;
prefix: string | null;
readonly localName: string | null;
textContent: string | null;
insertBefore(newChild: Node, refChild: Node | null): Node;
replaceChild(newChild: Node, oldChild: Node): Node;
removeChild(oldChild: Node): Node;
appendChild(newChild: Node): Node;
hasChildNodes(): boolean;
cloneNode(deep: boolean): Node;
normalize(): void;
isSupported(feature: string, version: string): boolean;
hasAttributes(): boolean;
isDefaultNamespace(namespaceURI: string | null): boolean;
lookupNamespaceURI(prefix: string | null): string | null;
}Usage Examples:
const { DOMParser } = require('xmldom');
const parser = new DOMParser();
const doc = parser.parseFromString('<items></items>', 'text/xml');
// Build tree structure
const container = doc.documentElement;
const item1 = doc.createElement('item');
const item2 = doc.createElement('item');
const item3 = doc.createElement('item');
item1.appendChild(doc.createTextNode('First item'));
item2.appendChild(doc.createTextNode('Second item'));
item3.appendChild(doc.createTextNode('Third item'));
// Add children in order
container.appendChild(item1);
container.appendChild(item2);
container.appendChild(item3);
// Insert new item at beginning
const newFirst = doc.createElement('item');
newFirst.appendChild(doc.createTextNode('New first item'));
container.insertBefore(newFirst, container.firstChild);
// Replace middle item
const replacement = doc.createElement('item');
replacement.appendChild(doc.createTextNode('Replacement item'));
container.replaceChild(replacement, item2);
// Remove last item
container.removeChild(item3);
// Clone structure
const clonedContainer = container.cloneNode(true);
console.log(clonedContainer.childNodes.length); // Same as original
// Tree traversal
let current = container.firstChild;
while (current) {
console.log(current.textContent);
current = current.nextSibling;
}Methods for managing text content within elements and text nodes.
/**
* CharacterData interface for text-containing nodes
*/
interface CharacterData extends Node {
data: string;
readonly length: number;
substringData(offset: number, count: number): string;
appendData(arg: string): void;
insertData(offset: number, arg: string): void;
deleteData(offset: number, count: number): void;
replaceData(offset: number, count: number, arg: string): void;
}
/**
* Text interface for text nodes
*/
interface Text extends CharacterData {
splitText(offset: number): Text;
}
/**
* Comment interface for comment nodes
*/
interface Comment extends CharacterData {
}
/**
* CDATASection interface for CDATA sections
*/
interface CDATASection extends Text {
}Usage Examples:
const { DOMParser } = require('xmldom');
const parser = new DOMParser();
const doc = parser.parseFromString('<article></article>', 'text/xml');
// Create and manipulate text content
const paragraph = doc.createElement('p');
const text = doc.createTextNode('This is the initial text content.');
paragraph.appendChild(text);
// Use CharacterData methods
console.log(text.length); // 33
console.log(text.substringData(12, 7)); // "initial"
text.appendData(' More text added.');
text.insertData(33, ' Additional content.');
text.replaceData(0, 4, 'That');
console.log(text.data); // Modified text content
// Split text node
const secondText = text.splitText(20);
console.log(paragraph.childNodes.length); // 2 text nodes
// Work with CDATA sections
const cdata = doc.createCDATASection('<script>alert("Hello");</script>');
paragraph.appendChild(cdata);
console.log(cdata.data); // Script content preserved
// Use textContent property (DOM Level 3)
paragraph.textContent = 'Replaced all content';
console.log(paragraph.childNodes.length); // 1 text node
// Comments
const comment = doc.createComment('This is a comment');
doc.documentElement.appendChild(comment);
comment.data = 'Updated comment text';Comprehensive attribute handling including both simple attribute methods and attribute node manipulation.
/**
* Attr interface representing element attributes
*/
interface Attr extends Node {
readonly name: string;
readonly specified: boolean;
value: string;
readonly ownerElement: Element | null;
}
/**
* NamedNodeMap interface for attribute collections
*/
interface NamedNodeMap {
readonly length: number;
getNamedItem(name: string): Node | null;
setNamedItem(arg: Node): Node | null;
removeNamedItem(name: string): Node;
item(index: number): Node | null;
getNamedItemNS(namespaceURI: string | null, localName: string): Node | null;
setNamedItemNS(arg: Node): Node | null;
removeNamedItemNS(namespaceURI: string | null, localName: string): Node;
}Usage Examples:
const { DOMParser } = require('xmldom');
const parser = new DOMParser();
const doc = parser.parseFromString('<products></products>', 'text/xml');
const product = doc.createElement('product');
// Simple attribute operations
product.setAttribute('id', 'P123');
product.setAttribute('name', 'Widget');
product.setAttribute('price', '29.99');
console.log(product.getAttribute('name')); // "Widget"
console.log(product.hasAttribute('discount')); // false
// Attribute node operations
const idAttr = doc.createAttribute('sku');
idAttr.value = 'W-001';
const oldAttr = product.setAttributeNode(idAttr);
console.log(oldAttr); // null (no previous attribute)
// Access attribute through NamedNodeMap
const attrs = product.attributes;
console.log(attrs.length); // 4 attributes
const priceAttr = attrs.getNamedItem('price');
priceAttr.value = '24.99'; // Modify through attribute node
// Iterate through attributes
for (let i = 0; i < attrs.length; i++) {
const attr = attrs.item(i);
console.log(`${attr.name}: ${attr.value}`);
}
// Remove attributes
product.removeAttribute('sku');
const removedAttr = product.removeAttributeNode(product.getAttributeNode('price'));
console.log(removedAttr.value); // "24.99"Work with document fragments for efficient DOM manipulation and temporary node storage.
/**
* DocumentFragment interface for lightweight document containers
*/
interface DocumentFragment extends Node {
// Inherits all Node methods
// When appended to another node, its children are moved, not the fragment itself
}Usage Examples:
const { DOMParser } = require('xmldom');
const parser = new DOMParser();
const doc = parser.parseFromString('<container></container>', 'text/xml');
// Create document fragment for batch operations
const fragment = doc.createDocumentFragment();
// Build content in fragment
for (let i = 1; i <= 5; i++) {
const item = doc.createElement('item');
item.setAttribute('id', i.toString());
item.appendChild(doc.createTextNode(`Item ${i}`));
fragment.appendChild(item);
}
console.log(fragment.childNodes.length); // 5 items
// Append fragment to document (moves all children)
doc.documentElement.appendChild(fragment);
console.log(fragment.childNodes.length); // 0 (children moved)
console.log(doc.documentElement.childNodes.length); // 5 itemsInstall with Tessl CLI
npx tessl i tessl/npm-xmldom