0
# DOM Tree Manipulation
1
2
Complete W3C DOM Level 2 Core implementation for creating, accessing, and modifying document trees. Provides full node hierarchy with standard manipulation methods.
3
4
## Capabilities
5
6
### Document Class
7
8
Root document node that serves as the factory for creating other nodes and provides document-wide query methods.
9
10
```javascript { .api }
11
/**
12
* Represents the root of a DOM tree
13
* Provides factory methods for creating nodes and document-wide queries
14
*/
15
class Document extends Node {
16
readonly nodeType: 9; // DOCUMENT_NODE
17
readonly nodeName: '#document';
18
readonly contentType: string; // MIME type used during parsing
19
readonly type: 'html' | 'xml'; // Document type
20
readonly implementation: DOMImplementation;
21
readonly doctype: DocumentType | null;
22
readonly documentElement: Element | null; // Root element
23
24
// Node creation methods
25
createElement(tagName: string): Element;
26
createElementNS(namespace: string | null, qualifiedName: string): Element;
27
createTextNode(data: string): Text;
28
createComment(data: string): Comment;
29
createCDATASection(data: string): CDATASection;
30
createAttribute(localName: string): Attr;
31
createAttributeNS(namespace: string | null, qualifiedName: string): Attr;
32
createDocumentFragment(): DocumentFragment;
33
createProcessingInstruction(target: string, data: string): ProcessingInstruction;
34
35
// Query methods
36
getElementById(elementId: string): Element | null;
37
getElementsByTagName(qualifiedName: string): LiveNodeList<Element>;
38
getElementsByTagNameNS(namespaceURI: string | null, localName: string): LiveNodeList<Element>;
39
getElementsByClassName(classNames: string): LiveNodeList<Element>;
40
41
// Node import
42
importNode<T extends Node>(node: T, deep?: boolean): T;
43
}
44
```
45
46
**Usage Examples:**
47
48
```javascript
49
const { DOMParser } = require('@xmldom/xmldom');
50
51
const parser = new DOMParser();
52
const doc = parser.parseFromString('<root></root>', 'text/xml');
53
54
// Create elements
55
const element = doc.createElement('item');
56
element.setAttribute('id', '123');
57
element.textContent = 'Item content';
58
59
// Create elements with namespaces
60
const nsElement = doc.createElementNS('http://example.com', 'ns:item');
61
62
// Query elements
63
const root = doc.documentElement;
64
const items = doc.getElementsByTagName('item');
65
const itemById = doc.getElementById('123');
66
67
// Create other node types
68
const textNode = doc.createTextNode('Hello world');
69
const comment = doc.createComment('This is a comment');
70
const cdata = doc.createCDATASection('Raw content');
71
```
72
73
### Element Class
74
75
Represents XML/HTML elements with attributes and child elements.
76
77
```javascript { .api }
78
/**
79
* Represents an element in the DOM tree
80
* Provides attribute manipulation and element-specific query methods
81
*/
82
class Element extends Node {
83
readonly nodeType: 1; // ELEMENT_NODE
84
readonly tagName: string; // Uppercase qualified name
85
readonly attributes: NamedNodeMap;
86
87
// Attribute methods
88
getAttribute(qualifiedName: string): string | null;
89
getAttributeNS(namespace: string | null, localName: string): string | null;
90
getAttributeNames(): string[];
91
getAttributeNode(qualifiedName: string): Attr | null;
92
getAttributeNodeNS(namespace: string | null, localName: string): Attr | null;
93
94
setAttribute(qualifiedName: string, value: string): void;
95
setAttributeNS(namespace: string | null, qualifiedName: string, value: string): void;
96
setAttributeNode(attr: Attr): Attr | null;
97
setAttributeNodeNS(attr: Attr): Attr | null;
98
99
removeAttribute(qualifiedName: string): void;
100
removeAttributeNS(namespace: string | null, localName: string): void;
101
removeAttributeNode(attr: Attr): Attr;
102
103
hasAttribute(qualifiedName: string): boolean;
104
hasAttributeNS(namespace: string | null, localName: string): boolean;
105
hasAttributes(): boolean;
106
107
// Element query methods
108
getElementsByTagName(qualifiedName: string): LiveNodeList<Element>;
109
getElementsByTagNameNS(namespaceURI: string | null, localName: string): LiveNodeList<Element>;
110
getElementsByClassName(classNames: string): LiveNodeList<Element>;
111
112
// Utility methods
113
getQualifiedName(): string;
114
}
115
```
116
117
**Usage Examples:**
118
119
```javascript
120
// Working with attributes
121
element.setAttribute('class', 'primary');
122
element.setAttribute('data-id', '42');
123
const className = element.getAttribute('class'); // 'primary'
124
125
// Namespace attributes
126
element.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', '#target');
127
const href = element.getAttributeNS('http://www.w3.org/1999/xlink', 'href');
128
129
// Check attributes
130
const hasClass = element.hasAttribute('class'); // true
131
const attributeNames = element.getAttributeNames(); // ['class', 'data-id', 'xlink:href']
132
133
// Query child elements
134
const children = element.getElementsByTagName('child');
135
const byClass = element.getElementsByClassName('highlight');
136
```
137
138
### Node Base Class
139
140
Abstract base class for all DOM nodes providing core tree manipulation methods.
141
142
```javascript { .api }
143
/**
144
* Abstract base class for all DOM nodes
145
* Provides core tree navigation and manipulation functionality
146
*/
147
class Node {
148
// Node type constants
149
static readonly ELEMENT_NODE: 1;
150
static readonly ATTRIBUTE_NODE: 2;
151
static readonly TEXT_NODE: 3;
152
static readonly CDATA_SECTION_NODE: 4;
153
static readonly PROCESSING_INSTRUCTION_NODE: 7;
154
static readonly COMMENT_NODE: 8;
155
static readonly DOCUMENT_NODE: 9;
156
static readonly DOCUMENT_TYPE_NODE: 10;
157
static readonly DOCUMENT_FRAGMENT_NODE: 11;
158
159
// Core properties
160
readonly nodeType: number;
161
readonly nodeName: string;
162
nodeValue: string | null;
163
readonly parentNode: Node | null;
164
readonly childNodes: NodeList;
165
readonly firstChild: Node | null;
166
readonly lastChild: Node | null;
167
readonly previousSibling: Node | null;
168
readonly nextSibling: Node | null;
169
readonly ownerDocument: Document | null;
170
readonly namespaceURI: string | null;
171
prefix: string | null;
172
readonly localName: string | null;
173
textContent: string | null;
174
readonly baseURI: string;
175
readonly isConnected: boolean;
176
177
// Location tracking (if locator enabled)
178
lineNumber?: number;
179
columnNumber?: number;
180
181
// Tree manipulation
182
appendChild(node: Node): Node;
183
insertBefore(node: Node, child: Node | null): Node;
184
removeChild(child: Node): Node;
185
replaceChild(node: Node, child: Node): Node;
186
cloneNode(deep?: boolean): Node;
187
188
// Tree queries
189
hasChildNodes(): boolean;
190
contains(other: Node | null | undefined): boolean;
191
getRootNode(options?: { composed?: boolean }): Node;
192
193
// Node comparison
194
isEqualNode(other: Node): boolean;
195
isSameNode(other: Node): boolean;
196
compareDocumentPosition(other: Node): number;
197
198
// Namespace methods
199
lookupNamespaceURI(prefix: string | null): string | null;
200
lookupPrefix(namespace: string | null): string | null;
201
isDefaultNamespace(namespace: string | null): boolean;
202
203
// Text normalization
204
normalize(): void;
205
206
// Legacy method
207
isSupported(feature: string, version: string): true;
208
}
209
```
210
211
**Usage Examples:**
212
213
```javascript
214
// Tree manipulation
215
const parent = doc.createElement('parent');
216
const child1 = doc.createElement('child1');
217
const child2 = doc.createElement('child2');
218
219
parent.appendChild(child1);
220
parent.insertBefore(child2, child1); // child2 is now first
221
222
// Node traversal
223
const firstChild = parent.firstChild;
224
const nextSibling = firstChild.nextSibling;
225
const allChildren = parent.childNodes;
226
227
// Node cloning
228
const shallowClone = parent.cloneNode(false); // No children
229
const deepClone = parent.cloneNode(true); // With all descendants
230
231
// Node comparison
232
const isEqual = node1.isEqualNode(node2);
233
const isSame = node1.isSameNode(node2);
234
```
235
236
### Text and Character Data
237
238
Node types for handling textual content.
239
240
```javascript { .api }
241
/**
242
* Abstract base class for nodes containing character data
243
*/
244
class CharacterData extends Node {
245
data: string; // The character data
246
readonly length: number; // Length of the data
247
248
appendData(data: string): void;
249
insertData(offset: number, data: string): void;
250
deleteData(offset: number, count: number): void;
251
replaceData(offset: number, count: number, data: string): void;
252
substringData(offset: number, count: number): string;
253
}
254
255
/**
256
* Represents text content in elements
257
*/
258
class Text extends CharacterData {
259
readonly nodeType: 3; // TEXT_NODE
260
readonly nodeName: '#text';
261
262
splitText(offset: number): Text;
263
}
264
265
/**
266
* Represents comments in markup
267
*/
268
class Comment extends CharacterData {
269
readonly nodeType: 8; // COMMENT_NODE
270
readonly nodeName: '#comment';
271
}
272
273
/**
274
* Represents CDATA sections in XML
275
*/
276
class CDATASection extends Text {
277
readonly nodeType: 4; // CDATA_SECTION_NODE
278
readonly nodeName: '#cdata-section';
279
}
280
281
/**
282
* Represents processing instructions
283
*/
284
class ProcessingInstruction extends CharacterData {
285
readonly nodeType: 7; // PROCESSING_INSTRUCTION_NODE
286
readonly target: string; // PI target name
287
data: string; // PI data content
288
}
289
```
290
291
**Usage Examples:**
292
293
```javascript
294
// Working with text nodes
295
const textNode = doc.createTextNode('Hello world');
296
textNode.appendData(' - more text');
297
textNode.replaceData(0, 5, 'Hi'); // 'Hi world - more text'
298
299
// Split text nodes
300
const secondPart = textNode.splitText(5); // Splits at position 5
301
302
// CDATA sections
303
const cdata = doc.createCDATASection('<script>alert("hi")</script>');
304
element.appendChild(cdata);
305
306
// Processing instructions
307
const pi = doc.createProcessingInstruction('xml-stylesheet', 'type="text/css" href="style.css"');
308
```
309
310
### Attributes
311
312
```javascript { .api }
313
/**
314
* Represents an attribute node
315
*/
316
class Attr extends Node {
317
readonly nodeType: 2; // ATTRIBUTE_NODE
318
readonly name: string; // Attribute name
319
readonly namespaceURI: string | null;
320
readonly prefix: string | null;
321
readonly ownerElement: Element | null;
322
readonly specified: true; // Always true in this implementation
323
value: string; // Attribute value
324
}
325
```
326
327
### Collection Classes
328
329
```javascript { .api }
330
/**
331
* Array-like collection of nodes
332
*/
333
class NodeList<T extends Node = Node> implements Iterable<T> {
334
readonly length: number;
335
336
item(index: number): T | null;
337
[index: number]: T;
338
[Symbol.iterator](): Iterator<T>;
339
}
340
341
/**
342
* Live collection that updates automatically with DOM changes
343
*/
344
interface LiveNodeList<T extends Node = Node> extends NodeList<T> {}
345
346
/**
347
* Collection of attributes accessible by name
348
*/
349
class NamedNodeMap implements Iterable<Attr> {
350
readonly length: number;
351
352
getNamedItem(qualifiedName: string): Attr | null;
353
getNamedItemNS(namespace: string | null, localName: string): Attr | null;
354
setNamedItem(attr: Attr): Attr | null;
355
setNamedItemNS(attr: Attr): Attr | null;
356
removeNamedItem(qualifiedName: string): Attr;
357
removeNamedItemNS(namespace: string | null, localName: string): Attr;
358
item(index: number): Attr | null;
359
360
[index: number]: Attr;
361
[Symbol.iterator](): Iterator<Attr>;
362
}
363
```
364
365
### Legacy Node Types
366
367
```javascript { .api }
368
/**
369
* Represents an entity node (legacy DOM feature)
370
* Primarily used in DTD processing and rarely encountered in modern XML
371
*/
372
class Entity extends Node {
373
readonly nodeType: 6; // ENTITY_NODE
374
readonly nodeName: string;
375
readonly publicId: string | null;
376
readonly systemId: string | null;
377
readonly notationName: string | null;
378
}
379
380
/**
381
* Represents an entity reference node (legacy DOM feature)
382
* Used to represent entity references in XML documents
383
*/
384
class EntityReference extends Node {
385
readonly nodeType: 5; // ENTITY_REFERENCE_NODE
386
readonly nodeName: string; // The entity name
387
}
388
389
/**
390
* Represents a notation node (legacy DOM feature)
391
* Used in DTD declarations to define data formats
392
*/
393
class Notation extends Node {
394
readonly nodeType: 12; // NOTATION_NODE
395
readonly nodeName: string;
396
readonly publicId: string | null;
397
readonly systemId: string | null;
398
}
399
```
400
401
**Usage Examples:**
402
403
```javascript
404
const { DOMParser, Entity, EntityReference, Notation } = require('@xmldom/xmldom');
405
406
// These node types are typically created during DTD processing
407
// and are rarely used in modern XML applications
408
409
function checkNodeType(node) {
410
switch (node.nodeType) {
411
case Entity.ENTITY_NODE:
412
console.log(`Entity: ${node.nodeName}`);
413
break;
414
case EntityReference.ENTITY_REFERENCE_NODE:
415
console.log(`Entity Reference: ${node.nodeName}`);
416
break;
417
case Notation.NOTATION_NODE:
418
console.log(`Notation: ${node.nodeName}`);
419
break;
420
}
421
}
422
```
423
424
### Document Creation
425
426
```javascript { .api }
427
/**
428
* Factory for creating new documents and document types
429
*/
430
class DOMImplementation {
431
constructor();
432
433
createDocument(
434
namespaceURI: string | null,
435
qualifiedName: string,
436
doctype?: DocumentType | null
437
): Document;
438
439
createDocumentType(
440
qualifiedName: string,
441
publicId?: string,
442
systemId?: string
443
): DocumentType;
444
445
createHTMLDocument(title?: string | false): Document;
446
447
// Deprecated but always returns true
448
hasFeature(feature: string, version?: string): true;
449
}
450
451
/**
452
* Represents a document type declaration
453
*/
454
class DocumentType extends Node {
455
readonly nodeType: 10; // DOCUMENT_TYPE_NODE
456
readonly name: string;
457
readonly publicId: string;
458
readonly systemId: string;
459
readonly internalSubset: string;
460
}
461
462
/**
463
* Lightweight document container
464
*/
465
class DocumentFragment extends Node {
466
readonly nodeType: 11; // DOCUMENT_FRAGMENT_NODE
467
readonly ownerDocument: Document;
468
469
getElementById(elementId: string): Element | null;
470
}
471
```
472
473
**Usage Examples:**
474
475
```javascript
476
// Create new documents
477
const impl = new DOMImplementation();
478
const doctype = impl.createDocumentType('html', '', '');
479
const htmlDoc = impl.createDocument('http://www.w3.org/1999/xhtml', 'html', doctype);
480
481
// Document fragments for efficient DOM construction
482
const fragment = doc.createDocumentFragment();
483
for (let i = 0; i < 10; i++) {
484
const item = doc.createElement('item');
485
item.textContent = `Item ${i}`;
486
fragment.appendChild(item);
487
}
488
parent.appendChild(fragment); // Adds all items at once
489
```