XML Parsing in JavaScript — Complete Guide with DOMParser and Node.js
In this tutorial, you'll learn about XML Parsing in JavaScript. We cover key concepts, practical examples, and best practices.
XML parsing in JavaScript uses DOMParser in browsers and libraries like xml2js and fast-xml-parser in Node.js, enabling XML processing for everything from configuration files to API response handling.
What You'll Learn
- Parsing XML in the browser with DOMParser
- Converting XML to JSON in Node.js with xml2js
- Using fast-xml-parser for high-performance parsing
- Evaluating XPath expressions in XML documents
Why XML Parsing in JavaScript Matters
JavaScript runs everywhere — browsers, servers (Node.js), and desktop apps. Many legacy APIs still return XML, configuration files use XML formats, and SVG graphics are XML-based. Doda Browser uses DOMParser to parse XML-based browser configuration profiles and bookmark files directly in the browser frontend.
Learning Path
flowchart LR A[XML Basics] --> B[XML Parsing Python] B --> C[XML Parsing Java] C --> D[XML Parsing JavaScript
You are here] D --> E[XML Schema XSD]
Sample XML Data
<?xml version="1.0" encoding="UTF-8"?>
<library>
<book category="fiction" id="b1">
<title>The Hobbit</title>
<author>J.R.R. Tolkien</author>
<year>1937</year>
<price currency="USD">12.99</price>
</book>
<book category="non-fiction" id="b2">
<title>A Brief History of Time</title>
<author>Stephen Hawking</author>
<year>1988</year>
<price currency="GBP">9.99</price>
</book>
<book category="fiction" id="b3">
<title>1984</title>
<author>George Orwell</author>
<year>1949</year>
<price currency="USD">10.99</price>
</book>
</library>
Browser: Parsing with DOMParser
In the browser, DOMParser converts XML strings into a traversable DOM:
// XML string to parse
const xmlString = `<?xml version="1.0" encoding="UTF-8"?>
<library>
<book category="fiction" id="b1">
<title>The Hobbit</title>
<author>J.R.R. Tolkien</author>
<year>1937</year>
<price currency="USD">12.99</price>
</book>
<book category="non-fiction" id="b2">
<title>A Brief History of Time</title>
<author>Stephen Hawking</author>
<year>1988</year>
<price currency="GBP">9.99</price>
</book>
<book category="fiction" id="b3">
<title>1984</title>
<author>George Orwell</author>
<year>1949</year>
<price currency="USD">10.99</price>
</book>
</library>`;
// Parse XML
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlString, 'text/xml');
// Navigate the DOM
const books = xmlDoc.getElementsByTagName('book');
console.log('Number of books:', books.length);
for (let i = 0; i < books.length; i++) {
const book = books[i];
const title = book.getElementsByTagName('title')[0].textContent;
const author = book.getElementsByTagName('author')[0].textContent;
const year = book.getElementsByTagName('year')[0].textContent;
const price = book.getElementsByTagName('price')[0].textContent;
const category = book.getAttribute('category');
console.log(`${title} by ${author} (${year}) - $${price} [${category}]`);
}
// Expected output:
// Number of books: 3
// The Hobbit by J.R.R. Tolkien (1937) - $12.99 [fiction]
// A Brief History of Time by Stephen Hawking (1988) - $9.99 [non-fiction]
// 1984 by George Orwell (1949) - $10.99 [fiction]
Browser: XPath Evaluation
Browser DOMParser supports XPath for advanced querying:
const xmlString = `<?xml version="1.0" encoding="UTF-8"?>
<library>
<book category="fiction" id="b1">
<title>The Hobbit</title>
<author>J.R.R. Tolkien</author>
<year>1937</year>
<price currency="USD">12.99</price>
</book>
<book category="non-fiction" id="b2">
<title>A Brief History of Time</title>
<author>Stephen Hawking</author>
<year>1988</year>
<price currency="GBP">9.99</price>
</book>
<book category="fiction" id="b3">
<title>1984</title>
<author>George Orwell</author>
<year>1949</year>
<price currency="USD">10.99</price>
</book>
</library>`;
const xmlDoc = new DOMParser().parseFromString(xmlString, 'text/xml');
// XPath evaluation
function evaluateXPath(xpath, doc) {
const result = doc.evaluate(
xpath, doc, null,
XPathResult.ANY_TYPE, null
);
let node;
const values = [];
while ((node = result.iterateNext()) !== null) {
values.push(node.textContent || node.nodeValue);
}
return values;
}
// Query fiction book titles
const fictionTitles = evaluateXPath(
"//book["@category"='fiction']/title/text()", xmlDoc
);
console.log('Fiction titles:', fictionTitles);
// Query books with price under $11
const budgetTitles = evaluateXPath(
"//book[price < 11]/title/text()", xmlDoc
);
console.log('Budget titles:', budgetTitles);
// Expected output:
// Fiction titles: ['The Hobbit', '1984']
// Budget titles: ['A Brief History of Time', '1984']
Node.js: XML to JSON with xml2js
In Node.js, xml2js converts XML to JavaScript objects:
const fs = require('fs');
const xml2js = require('xml2js');
// Read XML file
const xmlData = fs.readFileSync('library.xml', 'utf-8');
// Parse XML to JS object
const parser = new xml2js.Parser({
explicitArray: false, // flatten single-element arrays
mergeAttrs: true // merge attributes into parent object
});
parser.parseString(xmlData, (err, result) => {
if (err) {
console.error('Parse error:', err);
return;
}
const library = result.library;
const books = library.book;
if (Array.isArray(books)) {
books.forEach(book => {
console.log(`${book.title} by ${book.author} (${book.year}) - $${book.price}`);
});
} else {
console.log(`${books.title} by ${books.author} (${books.year}) - $${books.price}`);
}
// Convert back to XML
const builder = new xml2js.Builder();
const xml = builder.buildObject(result);
console.log('\nRe-serialized XML:');
console.log(xml);
});
// Expected output:
// The Hobbit by J.R.R. Tolkien (1937) - $12.99
// A Brief History of Time by Stephen Hawking (1988) - $9.99
// 1984 by George Orwell (1949) - $10.99
//
// Re-serialized XML:
// <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
// <library>
// ...
// </library>
Node.js: fast-xml-parser
For better performance, use fast-xml-parser:
const { XMLParser, XMLBuilder, XMLValidator } = require('fast-xml-parser');
const xmlData = require('fs').readFileSync('library.xml', 'utf-8');
// Validate XML first
const isValid = XMLValidator.validate(xmlData);
if (isValid !== true) {
console.error('Invalid XML:', isValid.err);
process.exit(1);
}
console.log('XML is valid');
// Parse with options
const parser = new XMLParser({
ignoreAttributes: false,
attributeNamePrefix: '@_',
isArray: (name) => name === 'book'
});
const jsonObj = parser.parse(xmlData);
const books = jsonObj.library.book;
books.forEach(book => {
console.log(`Title: ${book.title}`);
console.log(` Author: ${book.author}`);
console.log(` Category: ${book['"@_category"']}`);
console.log(` Price: ${book.price} (${book['"@_currency"'] || 'N/A'})`);
});
// Expected output:
// XML is valid
// Title: The Hobbit
// Author: J.R.R. Tolkien
// Category: fiction
// Price: 12.99 (USD)
// Title: A Brief History of Time
// Author: Stephen Hawking
// Category: non-fiction
// Price: 9.99 (GBP)
// Title: 1984
// Author: George Orwell
// Category: fiction
// Price: 10.99 (USD)
Creating XML in JavaScript
You can build XML programmatically in both browser and Node.js:
// Browser: create XML using DOM methods
function buildXml() {
const xmlDoc = document.implementation.createDocument(null, 'library');
const book = xmlDoc.createElement('book');
book.setAttribute('category', 'fiction');
xmlDoc.documentElement.appendChild(book);
const title = xmlDoc.createElement('title');
title.textContent = 'Dune';
book.appendChild(title);
const author = xmlDoc.createElement('author');
author.textContent = 'Frank Herbert';
book.appendChild(author);
const year = xmlDoc.createElement('year');
year.textContent = '1965';
book.appendChild(year);
// Serialize to string
const serializer = new XMLSerializer();
return serializer.serializeToString(xmlDoc);
}
const xml = buildXml();
console.log(xml);
// Expected output:
// <?xml version="1.0" encoding="UTF-8"?>
// <library>
// <book category="fiction">
// <title>Dune</title>
// <author>Frank Herbert</author>
// <year>1965</year>
// </book>
// </library>
Node.js: Build XML with fast-xml-parser
const { XMLBuilder } = require('fast-xml-parser');
const builder = new XMLBuilder({
format: true,
ignoreAttributes: false,
attributeNamePrefix: '@_'
});
const xmlObj = {
library: {
book: [{
'"@_category"': 'fiction',
title: 'Dune',
author: 'Frank Herbert',
year: 1965
}, {
'"@_category"': 'sci-fi',
title: 'Neuromancer',
author: 'William Gibson',
year: 1984
}]
}
};
const xmlOutput = builder.build(xmlObj);
console.log(xmlOutput);
// Expected output:
// <?xml version="1.0" encoding="UTF-8"?>
// <library>
// <book category="fiction">
// <title>Dune</title>
// <author>Frank Herbert</author>
// <year>1965</year>
// </book>
// <book category="sci-fi">
// <title>Neuromancer</title>
// <author>William Gibson</author>
// <year>1984</year>
// </book>
// </library>
Security Angle
XML parsing in JavaScript is vulnerable to XXE and entity expansion in Node.js parsers that resolve external entities. Doda Browser disables external entity resolution in its XML configuration parser:
const { XMLParser } = require('fast-xml-parser');
// Secure parser configuration
const parser = new XMLParser({
ignoreAttributes: false,
attributeNamePrefix: '@_',
// Prevent XXE and entity expansion
processEntities: false,
htmlEntities: false,
// Limit nesting depth to prevent billion laughs
maxDepth: 50
});
try {
const result = parser.parse(untrustedXml);
console.log('Parsed safely');
} catch (err) {
console.error('Parse error (possible XXE attempt):', err.message);
}
In browsers, DOMParser does not resolve external entities by default, making it inherently safer for untrusted XML.
Common Mistakes
1. Assuming xml2js always returns arrays
xml2js returns arrays only for repeated elements. With explicitArray: false, single elements become plain objects. Always check the type or set isArray in fast-xml-parser.
2. Not handling parse errors
DOMParser does not throw on invalid XML — it returns a document with a parsererror element. Always check for parsererror elements after parsing.
3. Forgetting to handle XML namespaces in XPath
Browser XPath requires namespace resolvers for namespace-prefixed queries. Without them, //ns:title throws an error.
4. Confusing XML DOM methods with HTML DOM
XML elements don't have the innerHTML property. Use textContent and getElementsByTagName instead.
Practice Questions
How do you parse XML in a browser? Use DOMParser:
new DOMParser().parseFromString(xmlString, 'text/xml').What is the difference between xml2js and fast-xml-parser? xml2js is older, callback-based, and slower. fast-xml-parser is faster, supports validation, and has better attribute handling.
How do you check for XML parse errors with DOMParser? Check if the returned document contains a
parsererrorelement:xmlDoc.querySelector('parsererror').
Challenge: Write a Node.js script that reads an RSS feed XML, converts it to JSON, filters articles published in the last 7 days, and outputs them as an HTML list with links and dates.
FAQ
Try It Yourself
Run the Node.js examples with these commands:
# Install dependencies
npm install xml2js fast-xml-parser
# Save any example as parse.js and run:
node parse.js
# Expected output varies by example
# but follows the patterns shown above
For browser examples, open the browser console and paste the code directly.
What's Next
| Tutorial | What You'll Learn |
|---|---|
| XML Basics — Complete Guide | Foundational XML concepts |
| XML Parsing in Python | Parse XML with Python's ElementTree and lxml |
| XML Parsing in Java | Parse XML with DOM, SAX, StAX, and JAXB in Java |
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro. Updated 2026-06-23.
What's Next
Congratulations on completing this XML Parsing in JavaScript tutorial! Here's where to go from here:
- Practice daily — Consistency is more important than long study sessions
- Build a project — Create a browser tool that parses XML files and displays them as a table
- Explore related topics — Check out other XML tutorials in this category
- Join the community — Discuss with other learners and share your progress
Remember: every expert was once a beginner. Keep coding!
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro