Skip to content

XML Parsing in JavaScript — Complete Guide with DOMParser and Node.js

DodaTech Updated 2026-06-23 9 min read

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

  1. How do you parse XML in a browser? Use DOMParser: new DOMParser().parseFromString(xmlString, 'text/xml').

  2. 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.

  3. How do you check for XML parse errors with DOMParser? Check if the returned document contains a parsererror element: 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

How do I parse XML in the browser?

Use the DOMParser API: const doc = new DOMParser().parseFromString(xmlStr, 'text/xml').

What is the best XML parser for Node.js?

fast-xml-parser is the fastest and most feature-rich. xml2js is simpler but slower. Choose based on your performance needs.

Can JavaScript evaluate XPath on XML?

Yes. Browsers support document.evaluate() for XPath. In Node.js, use the xpath library with DOMParser.

How do I convert XML to JSON in JavaScript?

Use xml2js.parseString() or fast-xml-parser's XMLParser.parse() to convert XML to JavaScript objects.

Is JavaScript XML parsing vulnerable to XXE?

Browser DOMParser is safe. Node.js parsers may resolve entities by default — configure them to disable external entity resolution.

How do I create XML from scratch in JavaScript?

In browsers, use document.implementation.createDocument() and XMLSerializer. In Node.js, use xml2js.Builder or fast-xml-parser's XMLBuilder.

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