namespace

XML

namespace XML

XML related APIs

  • interface Comment

    <!--comment--> among a Node's children.

  • interface Document

    A parsed document in the compact shape: exactly one key, the root element's name. This is also what importing an .xml file evaluates to.

  • interface Element

    An element that has attributes or child elements, in the compact shape.

    • "@name" — one per attribute, holding its value.
    • "#text" — the element's own character data, exactly, when it has any: its text runs concatenated, leaving out only whitespace-only runs that sit between child elements (layout).
    • any other key — a child element name, holding that child's Value, or an array of them when the name occurs more than once in this element.

    Keys are in document order: attributes first, then child names and "#text" in order of first appearance. @ and # cannot begin an XML name, so these keys never collide with element names.

  • interface Node

    An element in the tree parse returns with { compact: false }.

    • attributes: Record<string, string>

      Attribute values by name as written, in document order, after attribute-value normalization and with defaults declared in the internal DTD subset applied. Namespace declarations (xmlns, xmlns:*) are ordinary attributes.

    • children: string | Node | Comment | ProcessingInstruction[]

      The element's content in document order: character data as strings (exact — CDATA sections, character references and internal entities expanded, whitespace untouched, adjacent text merged into one string), child elements, comments and processing instructions. An object here is an element if it has name, a comment if it has comment, and a processing instruction if it has target.

    • name: string

      The element name as written, including any namespace prefix ("soap:Envelope").

  • interface NodeInput

    A Node as stringify accepts it: attributes and children may be omitted, scalars may stand where text goes, and null/undefined entries are skipped.

  • interface ParseOptions

    • compact?: boolean

      Selects the shape of the result.

      • true (default): the compact Document — elements keyed by name, leaves as strings. The shape for data. It does not keep the relative order of differently named siblings, where text sat relative to child elements, comments, or processing instructions.
      • false: the root element as a Node tree, which keeps all of those, in document order. The shape for documents.

      Neither shape represents the XML declaration, the document type declaration, or anything outside the root element.

  • interface ProcessingInstruction

    <?target data?> among a Node's children.

    • data: string

      The text after the whitespace that follows the target; "" when there is none.

    • target: string
  • type Scalar =
    | string
    | number
    | boolean
    | bigint
    | Date

    A value stringify writes as text: String(v), or the ISO string of a Date.

  • type Value = string | Element

    An element in the compact shape parse returns by default: its character data (a string) when it has no attributes and no child elements, otherwise an Element.

  • function parse(
    input: string | ArrayBufferLike | TypedArray<ArrayBufferLike> | DataView<ArrayBufferLike> | Blob,
    options?: ParseOptions & { compact: true }

    Parse an XML 1.0 document.

    Bun.XML is a conforming, non-validating XML processor. The document — including any internal DTD subset — must be well-formed or a SyntaxError is thrown; there is no lenient mode. Internal entities are expanded (within an expansion limit), attribute values are normalized, and attribute defaults declared in the internal subset are applied. External DTDs and external entities are never read. Nothing is coerced: every value is a string.

    compact selects a structure; it never alters character data. The text of an element is the same in both shapes — as written, whitespace included. The compact shape only does what having a single "#text" forces: an element's text runs are concatenated, and a whitespace-only run between child elements (the document's layout) is left out.

    A reference to an entity that only an unread external DTD could declare is not an error (XML 1.0 §4.1) and is kept in the text as written ("&name;" — indistinguishable afterwards from an escaped &amp;name;).

    A string is parsed as already-decoded text. Bytes (Buffer, TypedArray, DataView, ArrayBuffer, Blob) are decoded per the XML rules: a byte-order mark or the encoding declared in <?xml ...?> selects UTF-8, UTF-16, or ISO-8859-1; other encodings throw.

    @param input

    The XML document

    import { XML } from "bun";
    
    XML.parse(`<order id="A1"><item sku="x">Tea</item><item sku="y">Mug</item><paid/></order>`);
    // {
    //   order: {
    //     "@id": "A1",
    //     item: [ { "@sku": "x", "#text": "Tea" }, { "@sku": "y", "#text": "Mug" } ],
    //     paid: "",
    //   },
    // }
    
    XML.parse(`<p>Hello <b>world</b>!<!-- bye --></p>`, { compact: false });
    // {
    //   name: "p",
    //   attributes: {},
    //   children: [ "Hello ", { name: "b", attributes: {}, children: ["world"] }, "!", { comment: " bye " } ],
    // }
    function parse(
    input: string | ArrayBufferLike | TypedArray<ArrayBufferLike> | DataView<ArrayBufferLike> | Blob,
    options: ParseOptions & { compact: false }
    ): Node;

    Parse an XML 1.0 document.

    Bun.XML is a conforming, non-validating XML processor. The document — including any internal DTD subset — must be well-formed or a SyntaxError is thrown; there is no lenient mode. Internal entities are expanded (within an expansion limit), attribute values are normalized, and attribute defaults declared in the internal subset are applied. External DTDs and external entities are never read. Nothing is coerced: every value is a string.

    compact selects a structure; it never alters character data. The text of an element is the same in both shapes — as written, whitespace included. The compact shape only does what having a single "#text" forces: an element's text runs are concatenated, and a whitespace-only run between child elements (the document's layout) is left out.

    A reference to an entity that only an unread external DTD could declare is not an error (XML 1.0 §4.1) and is kept in the text as written ("&name;" — indistinguishable afterwards from an escaped &amp;name;).

    A string is parsed as already-decoded text. Bytes (Buffer, TypedArray, DataView, ArrayBuffer, Blob) are decoded per the XML rules: a byte-order mark or the encoding declared in <?xml ...?> selects UTF-8, UTF-16, or ISO-8859-1; other encodings throw.

    @param input

    The XML document

    import { XML } from "bun";
    
    XML.parse(`<order id="A1"><item sku="x">Tea</item><item sku="y">Mug</item><paid/></order>`);
    // {
    //   order: {
    //     "@id": "A1",
    //     item: [ { "@sku": "x", "#text": "Tea" }, { "@sku": "y", "#text": "Mug" } ],
    //     paid: "",
    //   },
    // }
    
    XML.parse(`<p>Hello <b>world</b>!<!-- bye --></p>`, { compact: false });
    // {
    //   name: "p",
    //   attributes: {},
    //   children: [ "Hello ", { name: "b", attributes: {}, children: ["world"] }, "!", { comment: " bye " } ],
    // }
    function parse(
    input: string | ArrayBufferLike | TypedArray<ArrayBufferLike> | DataView<ArrayBufferLike> | Blob,
    options?: ParseOptions

    Parse an XML 1.0 document.

    Bun.XML is a conforming, non-validating XML processor. The document — including any internal DTD subset — must be well-formed or a SyntaxError is thrown; there is no lenient mode. Internal entities are expanded (within an expansion limit), attribute values are normalized, and attribute defaults declared in the internal subset are applied. External DTDs and external entities are never read. Nothing is coerced: every value is a string.

    compact selects a structure; it never alters character data. The text of an element is the same in both shapes — as written, whitespace included. The compact shape only does what having a single "#text" forces: an element's text runs are concatenated, and a whitespace-only run between child elements (the document's layout) is left out.

    A reference to an entity that only an unread external DTD could declare is not an error (XML 1.0 §4.1) and is kept in the text as written ("&name;" — indistinguishable afterwards from an escaped &amp;name;).

    A string is parsed as already-decoded text. Bytes (Buffer, TypedArray, DataView, ArrayBuffer, Blob) are decoded per the XML rules: a byte-order mark or the encoding declared in <?xml ...?> selects UTF-8, UTF-16, or ISO-8859-1; other encodings throw.

    @param input

    The XML document

    import { XML } from "bun";
    
    XML.parse(`<order id="A1"><item sku="x">Tea</item><item sku="y">Mug</item><paid/></order>`);
    // {
    //   order: {
    //     "@id": "A1",
    //     item: [ { "@sku": "x", "#text": "Tea" }, { "@sku": "y", "#text": "Mug" } ],
    //     paid: "",
    //   },
    // }
    
    XML.parse(`<p>Hello <b>world</b>!<!-- bye --></p>`, { compact: false });
    // {
    //   name: "p",
    //   attributes: {},
    //   children: [ "Hello ", { name: "b", attributes: {}, children: ["world"] }, "!", { comment: " bye " } ],
    // }
  • function stringify(
    replacer?: null,
    space?: string | number
    ): string;

    Serialize one element to XML: a NodeInput tree (any object with a string name and a children or attributes property), or a compact object with exactly one key naming the root element whose value follows the Element conventions.

    The result is that element's markup only — no XML declaration and no document type declaration; prepend them as text when writing a file (

    '<?xml version="1.0" encoding="UTF-8"?>
    ' + XML.stringify(doc)
    ). Because of that, results can be concatenated inside an enclosing element.

    The output is well-formed or stringify throws. & < > are escaped everywhere; ", tabs and newlines in attribute values, and carriage returns anywhere, are written as character references so they survive being parsed again. It throws for element, attribute or processing instruction names that are not XML names; for characters XML cannot contain (U+0000, other C0 controls except tab/newline/carriage return, U+FFFE, U+FFFF, unpaired surrogates); for -- inside a comment or ?> inside processing-instruction data; for an array at the root or inside another array; and for circular structures.

    Strings, numbers, booleans and bigints become text via String(), a Date its ISO string; null becomes an empty element (or leaves an attribute out); undefined, functions and symbols are skipped, as are symbol-keyed, non-enumerable and inherited properties. In the compact shape an array is one element per item and any other object is a child element.

    XML.parse(XML.stringify(value)) deep-equals value for anything XML.parse returned, in either shape.

    @param value

    The element to serialize

    @param replacer

    Reserved; must be undefined or null

    @param space

    Indentation for element-only content, as in JSON.stringify: a number of spaces (at most 10) or a string (its first 10 characters). An element with any text child is written on one line so character data is unchanged.

    @returns

    The XML, or undefined if value is undefined, a function, or a symbol

    import { XML } from "bun";
    
    XML.stringify({ order: { "@id": "A1", item: ["Tea", "Mug"], paid: null } });
    // '<order id="A1"><item>Tea</item><item>Mug</item><paid/></order>'
    
    XML.stringify({ name: "p", attributes: { class: "x" }, children: ["Hi ", { name: "b", children: ["!"] }] }, null, 2);
    // '<p class="x">Hi <b>!</b></p>'
    function stringify(
    value: unknown,
    replacer?: null,
    space?: string | number
    ): undefined | string;

    Serialize one element to XML: a NodeInput tree (any object with a string name and a children or attributes property), or a compact object with exactly one key naming the root element whose value follows the Element conventions.

    The result is that element's markup only — no XML declaration and no document type declaration; prepend them as text when writing a file (

    '<?xml version="1.0" encoding="UTF-8"?>
    ' + XML.stringify(doc)
    ). Because of that, results can be concatenated inside an enclosing element.

    The output is well-formed or stringify throws. & < > are escaped everywhere; ", tabs and newlines in attribute values, and carriage returns anywhere, are written as character references so they survive being parsed again. It throws for element, attribute or processing instruction names that are not XML names; for characters XML cannot contain (U+0000, other C0 controls except tab/newline/carriage return, U+FFFE, U+FFFF, unpaired surrogates); for -- inside a comment or ?> inside processing-instruction data; for an array at the root or inside another array; and for circular structures.

    Strings, numbers, booleans and bigints become text via String(), a Date its ISO string; null becomes an empty element (or leaves an attribute out); undefined, functions and symbols are skipped, as are symbol-keyed, non-enumerable and inherited properties. In the compact shape an array is one element per item and any other object is a child element.

    XML.parse(XML.stringify(value)) deep-equals value for anything XML.parse returned, in either shape.

    @param value

    The element to serialize

    @param replacer

    Reserved; must be undefined or null

    @param space

    Indentation for element-only content, as in JSON.stringify: a number of spaces (at most 10) or a string (its first 10 characters). An element with any text child is written on one line so character data is unchanged.

    @returns

    The XML, or undefined if value is undefined, a function, or a symbol

    import { XML } from "bun";
    
    XML.stringify({ order: { "@id": "A1", item: ["Tea", "Mug"], paid: null } });
    // '<order id="A1"><item>Tea</item><item>Mug</item><paid/></order>'
    
    XML.stringify({ name: "p", attributes: { class: "x" }, children: ["Hi ", { name: "b", children: ["!"] }] }, null, 2);
    // '<p class="x">Hi <b>!</b></p>'