0
# XML Serialization
1
2
XML serialization functionality for converting DOM nodes and documents back to XML strings with proper formatting, namespace handling, and entity encoding.
3
4
## Capabilities
5
6
### XMLSerializer Class
7
8
The XMLSerializer class provides the standard W3C interface for converting DOM nodes into XML string representations.
9
10
```javascript { .api }
11
/**
12
* W3C XMLSerializer interface for converting DOM nodes to XML strings
13
*/
14
class XMLSerializer {
15
constructor();
16
17
/**
18
* Serializes a DOM node and its descendants to an XML string
19
* @param node The DOM node to serialize (Document, Element, or any Node)
20
* @param isHtml Optional boolean for HTML serialization mode
21
* @param nodeFilter Optional filter function to control serialization
22
* @returns XML string representation of the node
23
*/
24
serializeToString(node: Node, isHtml?: boolean, nodeFilter?: (node: Node) => boolean): string;
25
}
26
```
27
28
**Usage Examples:**
29
30
```javascript
31
const { DOMParser, XMLSerializer } = require('xmldom');
32
33
// Parse a document
34
const parser = new DOMParser();
35
const doc = parser.parseFromString(`
36
<catalog xmlns="http://example.com/catalog">
37
<product id="123">
38
<name>Widget & Tools</name>
39
<price currency="USD">29.99</price>
40
<description><![CDATA[Special characters: < > & " ']]></description>
41
</product>
42
</catalog>
43
`, 'text/xml');
44
45
// Create serializer and convert back to string
46
const serializer = new XMLSerializer();
47
const xmlString = serializer.serializeToString(doc);
48
console.log(xmlString);
49
50
// Serialize individual elements
51
const product = doc.getElementsByTagName('product').item(0);
52
const productXml = serializer.serializeToString(product);
53
console.log(productXml);
54
55
// Serialize text nodes
56
const nameElement = doc.getElementsByTagName('name').item(0);
57
const textNode = nameElement.firstChild;
58
const textContent = serializer.serializeToString(textNode);
59
console.log(textContent); // "Widget & Tools"
60
```
61
62
### Node toString Method
63
64
All DOM nodes have a toString() method that provides convenient serialization without requiring a separate XMLSerializer instance.
65
66
```javascript { .api }
67
/**
68
* toString method available on all Node instances
69
* @returns XML string representation of the node
70
*/
71
toString(): string;
72
```
73
74
**Usage Examples:**
75
76
```javascript
77
const { DOMParser } = require('xmldom');
78
const parser = new DOMParser();
79
const doc = parser.parseFromString('<items><item>test</item></items>', 'text/xml');
80
81
// Direct toString() on document
82
console.log(doc.toString());
83
84
// toString() on elements
85
const item = doc.getElementsByTagName('item').item(0);
86
console.log(item.toString()); // "<item>test</item>"
87
88
// toString() on text nodes
89
const textNode = item.firstChild;
90
console.log(textNode.toString()); // "test"
91
92
// toString() on attributes
93
const attr = doc.createAttribute('id');
94
attr.value = '123';
95
item.setAttributeNode(attr);
96
console.log(attr.toString()); // 'id="123"'
97
```
98
99
### Namespace Serialization
100
101
Proper handling of XML namespaces during serialization, including namespace declarations and qualified names.
102
103
```javascript { .api }
104
// Namespace-aware serialization handles:
105
// - Namespace URI preservation
106
// - Prefix declarations
107
// - Default namespace handling
108
// - Namespace inheritance
109
```
110
111
**Usage Examples:**
112
113
```javascript
114
const { DOMParser, XMLSerializer } = require('xmldom');
115
const parser = new DOMParser();
116
const serializer = new XMLSerializer();
117
118
// Document with multiple namespaces
119
const doc = parser.parseFromString(`
120
<root xmlns="http://example.com/default"
121
xmlns:ns1="http://example.com/ns1"
122
xmlns:ns2="http://example.com/ns2">
123
<item>Default namespace item</item>
124
<ns1:item>Namespace 1 item</ns1:item>
125
<ns2:item xmlns:ns2="http://example.com/ns2-updated">Updated namespace</ns2:item>
126
</root>
127
`, 'text/xml');
128
129
// Serialization preserves namespace information
130
const serialized = serializer.serializeToString(doc);
131
console.log(serialized);
132
133
// Create elements with namespaces programmatically
134
const newDoc = parser.parseFromString('<root></root>', 'text/xml');
135
const nsElement = newDoc.createElementNS('http://example.com/custom', 'custom:element');
136
nsElement.setAttributeNS('http://example.com/custom', 'custom:attr', 'value');
137
newDoc.documentElement.appendChild(nsElement);
138
139
console.log(newDoc.toString());
140
// Includes necessary namespace declarations
141
```
142
143
### Entity Encoding
144
145
Automatic encoding of special characters and entities during serialization to ensure valid XML output.
146
147
```javascript { .api }
148
// Automatic entity encoding for:
149
// - < becomes <
150
// - > becomes > (in text content containing "]]>")
151
// - & becomes &
152
// - " becomes " (in attribute values)
153
// - ' becomes ' (in attribute values when needed)
154
```
155
156
**Usage Examples:**
157
158
```javascript
159
const { DOMParser, XMLSerializer } = require('xmldom');
160
const parser = new DOMParser();
161
const serializer = new XMLSerializer();
162
163
const doc = parser.parseFromString('<root></root>', 'text/xml');
164
165
// Create element with special characters
166
const element = doc.createElement('message');
167
element.setAttribute('type', 'text with "quotes" and <brackets>');
168
element.appendChild(doc.createTextNode('Content with < and > and & symbols'));
169
170
// Add CDATA section
171
const cdata = doc.createCDATASection('Raw content: <script>alert("test");</script>');
172
element.appendChild(cdata);
173
174
// Add text that needs entity encoding
175
const specialText = doc.createTextNode('Text ending with ]]> needs encoding');
176
element.appendChild(specialText);
177
178
doc.documentElement.appendChild(element);
179
180
// Serialization properly encodes entities
181
const result = serializer.serializeToString(doc);
182
console.log(result);
183
// Output will have proper entity encoding:
184
// - Attribute values with " for quotes
185
// - Text content with < and > where needed
186
// - CDATA sections preserved as-is
187
// - "]]>" sequences properly encoded in text
188
```
189
190
### HTML Serialization Support
191
192
Specialized handling for HTML content when serializing documents parsed with HTML MIME types.
193
194
```javascript { .api }
195
// HTML serialization differences:
196
// - Uses HTML entity references where appropriate
197
// - Handles void elements correctly
198
// - Preserves HTML-specific formatting
199
```
200
201
**Usage Examples:**
202
203
```javascript
204
const { DOMParser, XMLSerializer } = require('xmldom');
205
const parser = new DOMParser();
206
const serializer = new XMLSerializer();
207
208
// Parse HTML content
209
const htmlDoc = parser.parseFromString(`
210
<html xmlns="http://www.w3.org/1999/xhtml">
211
<head>
212
<title>Test Page</title>
213
</head>
214
<body>
215
<p>Paragraph with © copyright symbol</p>
216
<br/>
217
<img src="test.jpg" alt="Test image"/>
218
</body>
219
</html>
220
`, 'text/html');
221
222
// Serialize HTML document
223
const htmlString = serializer.serializeToString(htmlDoc);
224
console.log(htmlString);
225
// Preserves HTML entities and structure
226
227
// Work with individual HTML elements
228
const title = htmlDoc.getElementsByTagName('title').item(0);
229
console.log(title.toString()); // Includes HTML entities
230
```
231
232
### Custom Serialization Options
233
234
While XMLSerializer follows W3C standards, xmldom provides some control over serialization behavior through node manipulation.
235
236
**Usage Examples:**
237
238
```javascript
239
const { DOMParser, XMLSerializer } = require('xmldom');
240
const parser = new DOMParser();
241
const serializer = new XMLSerializer();
242
243
// Create document with processing instructions and comments
244
const doc = parser.parseFromString('<root></root>', 'text/xml');
245
246
// Add XML declaration equivalent (processing instruction)
247
const pi = doc.createProcessingInstruction('xml', 'version="1.0" encoding="UTF-8"');
248
doc.insertBefore(pi, doc.documentElement);
249
250
// Add comment
251
const comment = doc.createComment('Generated by xmldom');
252
doc.insertBefore(comment, doc.documentElement);
253
254
// Add content
255
const element = doc.createElement('data');
256
element.setAttribute('timestamp', new Date().toISOString());
257
element.appendChild(doc.createTextNode('Sample content'));
258
doc.documentElement.appendChild(element);
259
260
// Serialize complete document
261
const fullXml = serializer.serializeToString(doc);
262
console.log(fullXml);
263
// Includes processing instruction, comment, and content
264
265
// Serialize just the content (exclude processing instructions/comments)
266
const contentOnly = serializer.serializeToString(doc.documentElement);
267
console.log(contentOnly);
268
```
269
270
### Performance Considerations
271
272
Tips for efficient serialization of large DOM structures.
273
274
**Usage Examples:**
275
276
```javascript
277
const { DOMParser, XMLSerializer } = require('xmldom');
278
const parser = new DOMParser();
279
const serializer = new XMLSerializer();
280
281
// For large documents, consider serializing sections
282
const largeDoc = parser.parseFromString('<data></data>', 'text/xml');
283
284
// Build large structure
285
for (let i = 0; i < 1000; i++) {
286
const item = largeDoc.createElement('item');
287
item.setAttribute('id', i.toString());
288
item.appendChild(largeDoc.createTextNode(`Item ${i}`));
289
largeDoc.documentElement.appendChild(item);
290
}
291
292
// Serialize entire document
293
const fullSerialization = serializer.serializeToString(largeDoc);
294
295
// Or serialize sections for streaming/chunked processing
296
const items = largeDoc.getElementsByTagName('item');
297
const serializedItems = [];
298
for (let i = 0; i < items.length; i++) {
299
serializedItems.push(serializer.serializeToString(items.item(i)));
300
}
301
302
// Process sections as needed
303
serializedItems.forEach((itemXml, index) => {
304
// Process individual item XML strings
305
if (index % 100 === 0) {
306
console.log(`Processed ${index} items`);
307
}
308
});
309
```