fast-xml-parser

repository·master·Indexed 25 days ago

https://github.com/naturalintelligence/fast-xml-parser

A high-performance, pure JavaScript library for validating, parsing, and building XML. It supports CommonJS, ESM, and browser environments, and can handle files up to 100MB. The library provides the XMLParser class for converting XML to JS objects, XMLBuilder for converting JS objects to XML, and XMLValidator for syntactic validation. It includes extensive configuration options for attribute handling, CDATA, comments, and number parsing.

Tokens
18.6K
Snippets
60
Records
115
Agent score
80%

What's inside fast-xml-parser

  1. Install fast-xml-parser

    master

    You can install fast-xml-parser as a project dependency using npm or yarn, or install it globally to use it as a system command.

    To use it in a Node.js project:

    $ npm install fast-xml-parser
    # or
    $ yarn add fast-xml-parser

    To use it as a system command:

    $ npm install fast-xml-parser -g

    To use it on a webpage, include it via a CDN.

    $ npm install fast-xml-parser
  2. Process XML Processing Instructions (PI tags)

    master

    Fast XML Parser supports Processing Instructions (PI tags), but treats them as normal tags during parsing. To ensure attributes within PI tags are processed correctly, you must set ignoreAttributes: false and allowBooleanAttributes: true in your parser options.

    Note the following behavior:

    • PI tag names start with a ? character.
    • The #text property is always empty to maintain consistency with other parsed properties.
    • Attributes are parsed using the same logic as normal tags.
    const options = {
        ignoreAttributes: false,
        format: true,
        preserveOrder: true,
        allowBooleanAttributes: true
    };
    const parser = new XMLParser(options);
    let result = parser.parse(xmlData);
  3. Rebuild XML with Processing Instructions using XMLBuilder

    master

    To reconstruct XML containing Processing Instructions from a parsed JS ordered object, use XMLBuilder with the following configuration:

    • ignoreAttributes: false
    • preserveOrder: true
    • allowBooleanAttributes: true
    • suppressBooleanAttributes: true (optional, used to clean up boolean attribute output)

    This ensures that PI tags (starting with ?) and their attributes are correctly formatted in the output XML.

    const options = {
        ignoreAttributes: false,
        preserveOrder: true,
        allowBooleanAttributes: true,
        suppressBooleanAttributes: true
    };
    const builder = new XMLBuilder(options);
    const output = builder.build(result);
  4. Rebuild HTML from JS object using XMLBuilder

    master

    To convert a JS object back into an HTML document (round-tripping), you must use XMLBuilder with preserveOrder: true enabled in both the XMLParser and XMLBuilder configurations. This ensures the structure and order of elements are maintained.

    Required configuration for round-tripping:

    • In XMLParser: Set preserveOrder: true.
    • In XMLBuilder: Set preserveOrder: true, format: true, and suppressEmptyNode: true.
    const parsingOptions = {
        ignoreAttributes: false,
        preserveOrder: true,
        unpairedTags: ["hr", "br", "link", "meta"],
        stopNodes : [ "*.pre", "*.script"],
        processEntities: true,
        htmlEntities: true
    };
    const parser = new XMLParser(parsingOptions);
    let result = parser.parse(html);
    
    const builderOptions = {
        ignoreAttributes: false,
        format: true,
        preserveOrder: true,
        suppressEmptyNode: true,
        unpairedTags: ["hr", "br", "link", "meta"],
        stopNodes : [ "*.pre", "*.script"],
    };
    const builder = new XMLBuilder(builderOptions);
    const output = builder.build(result);
  5. Optimize performance with Expression pre-compilation

    master

    When using jPath: false and Expression objects in callbacks, always pre-compile your expressions outside of the callback. Creating a new Expression() inside a callback is extremely slow as it parses the pattern for every single node processed.

    // ✅ GOOD - Parse once, reuse many times
    const expr = new Expression("..user[id]");
    
    const parser = new XMLParser({
      stopNodes: [expr],
      jPath: false,
      tagValueProcessor: (tagName, val, matcher) => {
        if (matcher.matches(expr)) {
          // Fast matching - expression already parsed
        }
        return val;
      }
    });
    
    // ❌ BAD - Parse on every callback
    const parser = new XMLParser({
      jPath: false,
      tagValueProcessor: (tagName, val, matcher) => {
        // Slow - creates new Expression every time
        if (matcher.matches(new Expression("..user[id]"))) {
          // ...
        }
        return val;
      }
    });
  6. Migrate from fast-xml-parser to fast-xml-builder

    master

    The XMLBuilder functionality has been moved from the fast-xml-parser package to a dedicated standalone package called fast-xml-builder. To avoid bugs affecting the parser and to ensure future compatibility, you should migrate your imports. XMLBuilder will be removed from the fast-xml-parser package in the next major version.

    // From
    import { XMLBuilder } from "fast-xml-parser";
    
    // To
    import XMLBuilder from "fast-xml-builder";
  7. Use advanced pattern matching in stopNodes

    master

    Starting from v5.5.0, stopNodes supports powerful pattern matching via path-expression-matcher. You can use strings for simple patterns or Expression objects for complex logic including exact paths, deep wildcards, attribute conditions, position selectors, and namespaces.

    Note on Wildcards:

    • Using a string like "*.script" is automatically converted to "..script" (matches at any depth) for backward compatibility.
    • Using new Expression("*.script") matches only at one level. To match at any depth with an Expression object, use "..script" instead.
    import { Expression } from 'path-expression-matcher';
    
    const parser = new XMLParser({
      stopNodes: [
        "..script",                           // Deep wildcard - script anywhere
        "..style",                            // Deep wildcard - style anywhere
        new Expression("html.body.script"),   // Exact path
        new Expression("..pre"),              // Any pre tag
        new Expression("div[class=code]"),    // With attribute condition
        new Expression("item:first"),         // Position selector
        new Expression("ns::tag")             // Namespace support
      ]
    });