A pure JavaScript W3C standard-based (XML DOM Level 2 Core) DOMParser and XMLSerializer module
Convert DOM nodes back into XML strings with optional filtering and formatting control. Provides standards-compliant XML output generation.
The main serialization class that converts DOM nodes into XML string representations.
/**
* Serializes DOM nodes to XML strings
* Provides control over output formatting and node filtering
*/
class XMLSerializer {
constructor();
/**
* Serializes a DOM node and its descendants to an XML string
* @param node - The root node to serialize
* @param nodeFilter - Optional function to filter which nodes to include
* @returns XML string representation of the node tree
*/
serializeToString(node: Node, nodeFilter?: (node: Node) => boolean): string;
}Usage Examples:
const { DOMParser, XMLSerializer } = require('@xmldom/xmldom');
// Parse and serialize basic document
const parser = new DOMParser();
const doc = parser.parseFromString('<root><child>content</child></root>', 'text/xml');
const serializer = new XMLSerializer();
const xmlString = serializer.serializeToString(doc);
console.log(xmlString); // <?xml version="1.0"?><root><child>content</child></root>
// Serialize specific elements
const root = doc.documentElement;
const rootXml = serializer.serializeToString(root);
console.log(rootXml); // <root><child>content</child></root>
// Serialize with node filtering
const filteredXml = serializer.serializeToString(doc, (node) => {
// Only include element nodes and text nodes
return node.nodeType === Node.ELEMENT_NODE || node.nodeType === Node.TEXT_NODE;
});The serializer handles different node types according to XML standards:
Document Nodes:
Element Nodes:
Text Nodes:
<, >, &)CDATA Sections:
<![CDATA[...]]> markersComments:
<!-- ... --> formatProcessing Instructions:
<?target data?> formatFiltering Nodes:
const { DOMParser, XMLSerializer, Node } = require('@xmldom/xmldom');
const parser = new DOMParser();
const doc = parser.parseFromString(`
<root>
<!-- This is a comment -->
<data>Important content</data>
<metadata>Skip this</metadata>
<?instruction data?>
</root>
`, 'text/xml');
const serializer = new XMLSerializer();
// Only serialize elements and text, skip comments and PIs
const elementsOnly = serializer.serializeToString(doc, (node) => {
return node.nodeType === Node.ELEMENT_NODE ||
node.nodeType === Node.TEXT_NODE ||
node.nodeType === Node.DOCUMENT_NODE;
});
// Skip specific elements by tag name
const skipMetadata = serializer.serializeToString(doc, (node) => {
if (node.nodeType === Node.ELEMENT_NODE) {
return node.nodeName !== 'metadata';
}
return true;
});Handling Different Document Types:
// Serialize HTML document
const htmlDoc = parser.parseFromString('<html><body><p>Hello</p></body></html>', 'text/html');
const htmlString = serializer.serializeToString(htmlDoc);
// Serialize with namespaces
const nsDoc = parser.parseFromString(`
<root xmlns="http://example.com" xmlns:ns="http://other.com">
<child>Default namespace</child>
<ns:child>Other namespace</ns:child>
</root>
`, 'text/xml');
const nsString = serializer.serializeToString(nsDoc);
// Preserves namespace declarations and prefixesWorking with Document Fragments:
const fragment = doc.createDocumentFragment();
const elem1 = doc.createElement('item');
elem1.textContent = 'First item';
const elem2 = doc.createElement('item');
elem2.textContent = 'Second item';
fragment.appendChild(elem1);
fragment.appendChild(elem2);
// Serialize fragment (outputs child nodes without wrapper)
const fragmentXml = serializer.serializeToString(fragment);
console.log(fragmentXml); // <item>First item</item><item>Second item</item>Character Encoding and Escaping:
The serializer automatically handles XML character escaping:
const doc = parser.parseFromString('<root></root>', 'text/xml');
const element = doc.createElement('test');
// Special characters are automatically escaped
element.setAttribute('data', 'value with & < > " characters');
element.textContent = 'Text with <script> & "quotes"';
const escaped = serializer.serializeToString(element);
// Output: <test data="value with & < > " characters">Text with <script> & "quotes"</test>Error Handling:
try {
const result = serializer.serializeToString(someNode);
} catch (error) {
console.error('Serialization failed:', error.message);
// Handle cases like invalid node structures or circular references
}Serialization works seamlessly with all DOM manipulation operations:
const { DOMParser, XMLSerializer } = require('@xmldom/xmldom');
// Create and modify document
const parser = new DOMParser();
const doc = parser.parseFromString('<catalog></catalog>', 'text/xml');
// Add items dynamically
const catalog = doc.documentElement;
for (let i = 1; i <= 3; i++) {
const item = doc.createElement('item');
item.setAttribute('id', i.toString());
item.textContent = `Item ${i}`;
catalog.appendChild(item);
}
// Serialize the modified document
const serializer = new XMLSerializer();
const result = serializer.serializeToString(doc);
console.log(result);
// Output: <?xml version="1.0"?><catalog><item id="1">Item 1</item><item id="2">Item 2</item><item id="3">Item 3</item></catalog>The serializer produces compact XML output without additional formatting. For pretty-printed output, you would need to implement custom formatting or use external tools:
// The serializer produces compact output
const compactXml = serializer.serializeToString(doc);
// <root><child><grandchild>content</grandchild></child></root>
// For formatted output, you'd need to implement custom logic
function formatXml(xmlString) {
// Custom formatting implementation
// This is not provided by @xmldom/xmldom
}Install with Tessl CLI
npx tessl i tessl/npm-xmldom--xmldom