Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

In a browser, parse XML text with DOMParser using an XML MIME type such as application/xml, then check for a parsererror node before reading the document. In Node.js, use a package such as @xmldom/xmldom for a DOM-style result or @rgrove/parse-xml for an object tree. The right choice depends on your runtime and XML requirements.

Parse XML in a browser with DOMParser

DOMParser is a browser Web API that turns a string into a DOM Document. Use an XML MIME type, not text/html, so the input is interpreted with XML parsing rules. [MDN: parseFromString]

const xmlText = `<catalog><book id="b1">XML basics</book></catalog>`;
const parser = new DOMParser();
const doc = parser.parseFromString(xmlText, "application/xml");

const errorNode = doc.querySelector("parsererror");
if (errorNode) {
  throw new Error("The XML is not well formed");
}

const book = doc.querySelector("book");
if (!book) {
  throw new Error("Expected a <book> element");
}

console.log(book.getAttribute("id")); // "b1"
console.log(book.textContent);        // "XML basics"

The parser returns a document even when the source is malformed; in that case, the document contains a parsererror node. Check for it before querying for your expected elements. Error text and markup can vary by browser, so use the presence of the error node to branch rather than depending on a particular message. [MDN: parseFromString]

Choose the XML MIME type

The documented XML-related MIME types include application/xml, text/xml, application/xhtml+xml, and image/svg+xml. Choose the one appropriate to your document. For ordinary XML data, application/xml is a clear default. Passing text/html invokes HTML parsing behavior instead. [MDN: parseFromString; W3C DOM Parsing]

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Fetch an XML resource, then parse it

Retrieving a URL and parsing its contents are separate operations. Check the HTTP response first, read its body as text, then pass that text to DOMParser. This makes it easier to distinguish network or HTTP failures from malformed XML. [MDN: Parsing and serializing XML]

async function fetchXml(url) {
  const response = await fetch(url);
  if (!response.ok) {
    throw new Error(`HTTP ${response.status} while fetching XML`);
  }

  const xmlText = await response.text();
  const doc = new DOMParser().parseFromString(xmlText, "application/xml");
  if (doc.querySelector("parsererror")) {
    throw new Error("The response body is not well-formed XML");
  }

  return doc;
}

const doc = await fetchXml("https://example.com/feed.xml");
console.log(doc.documentElement.tagName);

Browser cross-origin rules still apply to fetch. If a request is blocked by the site’s CORS policy, parsing never occurs; the server must permit the request or your application must retrieve the resource through an authorized backend. A successful HTTP response also does not guarantee the body is XML: a server may return an HTML error page, which will fail XML parsing.

Read elements, attributes, and text

Begin with doc.documentElement to inspect the root element. Use DOM selectors or tree methods to locate data, getAttribute() for attributes, and textContent for text inside an element.

const root = doc.documentElement;
console.log(root.tagName);

const books = [...doc.querySelectorAll("book")].map((book) => ({
  id: book.getAttribute("id"),
  title: book.textContent.trim(),
}));
console.log(books);

textContent includes the text of descendant elements as well as direct text nodes. If mixed content or child structure matters, traverse the nodes rather than assuming the element contains only one simple string. Also distinguish a missing attribute (null) from an attribute whose value is an empty string.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Handle namespaces explicitly

XML vocabularies often qualify names with namespaces. A selector such as querySelector("item") assumes an unqualified element and may not match a namespaced one. Use namespace-aware DOM methods when the namespace URI is known:

const ns = "https://example.com/catalog";
const items = doc.getElementsByTagNameNS(ns, "item");
console.log(items.length);

Namespace identity is based on the namespace URI, not the prefix chosen in the document. If you use selectors for a namespace-heavy vocabulary, confirm that the selector mechanism and browser support match your needs. [MDN: Parsing and serializing XML; W3C DOM Parsing]

Parse XML in Node.js

DOMParser is a browser API, not a built-in Node.js global. Node.js applications commonly add a package. Two options documented for this task illustrate different output models:

Package Output model Relevant qualification
@xmldom/xmldom DOM-like document, with DOMParser and XMLSerializer Its documentation says the implementation is not fully feature-complete and may differ from standards behavior. [Project documentation]
@rgrove/parse-xml Object-tree representation Its documentation says it does not load external DTDs, validate against DTDs, or resolve custom DTD entity references. [Project documentation]

Review each project’s current documentation for supported Node.js versions, release and maintenance status, diagnostics, and XML feature behavior before adopting it. Do not assume that a package has the same behavior as a browser parser or supports every DTD-dependent document.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

DOM-style parsing with @xmldom/xmldom

Install the package in your project with your package manager, for example npm install @xmldom/xmldom. The following CommonJS example parses a string and checks for a parser error element:

const { DOMParser } = require("@xmldom/xmldom");

const xmlText = `<catalog><book id="b1">XML basics</book></catalog>`;
const doc = new DOMParser().parseFromString(xmlText, "application/xml");

const errors = doc.getElementsByTagName("parsererror");
if (errors.length > 0) {
  throw new Error("The XML could not be parsed");
}

const books = doc.getElementsByTagName("book");
if (books.length > 0) {
  console.log(books[0].getAttribute("id"));
  console.log(books[0].textContent);
}

For precise malformed-input handling, consult the package’s current documentation for its error-reporting and parser configuration options; do not rely on browser-specific parsererror text or assume identical diagnostics across implementations. [@xmldom/xmldom documentation]

Object-tree parsing with @rgrove/parse-xml

Install it with npm install @rgrove/parse-xml. Its documented API returns an object-tree representation rather than a DOM, so adapt access to the package’s documented node shape instead of using browser DOM selectors. A simple Node.js use is:

const parseXml = require("@rgrove/parse-xml");

const xmlText = `<catalog><book id="b1">XML basics</book></catalog>`;
const tree = parseXml(xmlText);
console.log(tree);

Inspect the package documentation for its precise tree structure and error behavior. Its stated DTD limitations matter if the source depends on external DTD loading, DTD validation, or custom DTD entity resolution. [@rgrove/parse-xml documentation]

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Choose a parser for your requirements

There is no universal best parser for every JavaScript project. Decide based on where the code runs, what representation downstream code needs, and which XML features the input actually uses.

  • Browser application: use the built-in DOMParser when a DOM document is useful and the browser is the runtime.
  • Node.js with DOM-oriented code: consider @xmldom/xmldom, while accounting for its documented differences from full standards behavior.
  • Node.js or browser code that prefers a tree object: consider @rgrove/parse-xml if its documented XML and DTD behavior matches the input.
  • DTD-dependent documents: verify support explicitly. In particular, @rgrove/parse-xml documents that it does not load external DTDs, validate against DTDs, or resolve custom DTD entity references.
  • Production dependency: compare current runtime compatibility, maintenance, malformed-input diagnostics, security characteristics, and the exact XML vocabulary and features you need.

Understand what successful parsing proves

A successful parse means the parser accepted the document as well-formed XML; it does not establish that the document follows your application’s schema or business rules. Validate required elements, permitted values, identifiers, and relationships separately when those constraints matter. [MDN: parseFromString]

Parsing also is not sanitization. The parsed content is initially in a separate in-memory document, but unsafe elements or attributes can become active if you insert nodes into the visible page. Treat XML-derived markup as untrusted, validate or sanitize it before insertion, and use Trusted Types protections where applicable. Values extracted from XML may also influence later actions such as resource requests; validate them at the point of use. [MDN: parseFromString]

Serialize a parsed document

If you need markup text from a DOM node, use XMLSerializer:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const serialized = new XMLSerializer().serializeToString(doc.documentElement);
console.log(serialized);

Serialization turns a DOM node back into text. It does not validate application rules or make that text safe to inject into an active page. In Node.js, availability and behavior depend on the parser package; @xmldom/xmldom documents an XMLSerializer implementation. [MDN: DOMParser; MDN: Parsing and serializing XML]

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshoot common XML parsing failures

Symptom Likely cause What to do
A parsererror appears The string is not well-formed XML, or the response is not actually XML. Inspect the raw response text; check for unescaped ampersands, mismatched tags, invalid nesting, or an HTML error page.
No expected element is found The actual root/structure differs from the assumption, or the element is namespaced. Inspect doc.documentElement; verify local name and namespace URI, and use namespace-aware methods when needed.
Fetch fails before parsing Network, HTTP, or browser cross-origin restrictions prevented a usable response. Check the rejected request, response.ok, and server CORS policy. Keep retrieval errors distinct from syntax errors.
Node.js reports DOMParser is not defined Browser APIs are not automatically available as Node.js globals. Install and import a suitable parser package, then use its documented API.
Different parser behavior or error details Implementations vary in standards coverage and diagnostics. Consult the chosen package’s documentation and test representative inputs, including malformed and namespaced XML.
DTD entities or validation do not behave as expected The selected parser may not implement the required DTD features. Check documented DTD behavior before relying on it; @rgrove/parse-xml lists specific DTD limitations.
XML-derived content behaves unexpectedly after insertion Parsing was mistaken for sanitization, or extracted values are being trusted. Sanitize or validate before DOM insertion and validate values again wherever they drive later actions.

Or skip the browser setup

If your goal is to capture a page as an image or PDF rather than parse an XML response, ScreenshotNeo offers a one-request screenshot API. It accepts a URL and returns a screenshot or PDF; this is separate from XML parsing.

ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before capture; bot checks, blank pages, and failed loads are never billed; its MCP server lets AI agents take screenshots; and 1,000 screenshots a month are free with no card, with paid plans starting at $5 for 3,000.

For a screenshot of a web page, the cURL call is:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo API documentation for request options. Sign up for 1,000 free screenshots a month with no card.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Frequently Asked Questions

Can I use DOMParser in Node.js without installing a package?

No. DOMParser is a browser Web API; Node.js code needs a parser package or another explicitly provided implementation.

Does parsing XML validate it against my application’s schema?

No. Parsing checks XML syntax and well-formedness; application-specific schema and business rules require separate validation.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.