XML

XML lives in runtime:serialization and runs in Rust: the string crosses the op boundary once and a JavaScript value comes back, so no intermediate document is built in the isolate for the collector to walk.

Parsing XML

Use XML.parse to convert an XML string directly into a JavaScript object.

JavaScript
import { XML } from "runtime:serialization";

const xmlData = `<user id="1"><name>Alice</name></user>`;

const parsed = XML.parse(xmlData);
console.log(parsed.user.name.$text); // "Alice"
console.log(parsed.user["@id"]);     // "1"

The root element is a key like any other — parse returns the document, not the root's contents. An attribute is prefixed @, and an element's own text is $text.

Validating XML

Use XML.validate to check if an XML string is well-formed.

JavaScript
import { XML } from "runtime:serialization";

const xmlData = `<user id="1"><name>Alice</name></user>`;

if (XML.validate(xmlData)) {
  console.log("XML is valid!");
}

const result = XML.validate("<invalid><xml>", { detailed: true });
console.log(result.valid); // false
console.log(result.error); // "Validation failed: ..."

Building XML

Use XML.build to serialize a JavaScript object back into an XML string.

JavaScript
import { XML } from "runtime:serialization";

const obj = {
  user: {
    "@id": "1",
    name: "Alice"
  }
};

const built = XML.build(obj);
console.log(built); // <user id="1"><name>Alice</name></user>

Streaming

XML.DecoderStream is a web TransformStream that takes XML chunks and emits one parsed object per direct child of the root element — one record at a time, so a document larger than memory never becomes a tree in the isolate. A single record that grows past 64 MiB unclosed is a RangeError, and nesting deeper than 256 levels is a parse error, on this path and on parse.

JavaScript
import { XML } from "runtime:serialization";

async function processMassiveFeed(fileStream) {
  // Pipe the chunks directly into the native streaming parser
  const objectStream = fileStream.pipeThrough(new XML.DecoderStream());

  // Use async iteration to consume parsed top-level element objects natively
  for await (const value of objectStream) {
    console.log(value);
  }
}

Performance

Measured against the parser each runtime would otherwise reach for — fast-xml-parser on Node.js and Deno, llrt:xml on LLRT — on the Benchmarks page, which renders the committed results rather than a number typed here.

Last updated on
Edit this page