XML-JS Converter
xml-js is a robust JavaScript library designed for converting between XML text and JavaScript objects or JSON text. It is currently stable at version 1.6.11 and receives active maintenance, with recent updates focusing on performance optimizations and new features like custom processing functions. A key differentiator is its ability to maintain the original order of XML elements during conversion to a JavaScript object, avoiding the common practice of merging same-named nodes into arrays by default, which is crucial for preserving document structure. It supports full XML compliance, parsing elements, attributes, texts, comments, CData, DOCTYPEs, XML declarations, and Processing Instructions. The library is also reversible, meaning conversions from XML to JS/JSON and back to XML will preserve the original data. It is known for its minimal dependencies and portability, working in both Node.js and browser environments.
Common errors
-
TypeError: xml2js is not a function
cause Incorrectly importing `xml2js` as a default export or attempting to access it directly on a `require`'d module that expects a single 'convert' object.fixEnsure you are using named imports for `xml2js` (e.g., `import { xml2js } from 'xml-js';`) or importing the entire module as a namespace (e.g., `import * as convert from 'xml-js';` then calling `convert.xml2js(...)`). For CommonJS, use `const { xml2js } = require('xml-js');` or `const convert = require('xml-js');` and then `convert.xml2js(...)`. -
Output XML does not match input structure, elements are reordered or missing.
cause Using `compact: true` mode for `xml2js` which simplifies the object structure and can lead to loss of element order or merging of same-named elements into arrays without preserving their original sequence relative to other unique elements.fixAlways use `{ compact: false }` for both `xml2js` and `js2xml` when precise XML structure, element order, and full reversibility are critical. This will represent elements as an array of objects, preserving their sequence. -
The 'text' content of an element appears as an empty object or incorrect type.
cause Mismatch between how text nodes are represented in 'compact' vs 'non-compact' modes. In non-compact, text is usually an object like `{ type: 'text', text: '...' }`, while in compact mode, it might be directly accessible or nested differently depending on other attributes/children.fixConsult the documentation for the specific structure generated by `compact: true` versus `compact: false`. When `compact: true`, text nodes are often accessed directly from the element property, or as `_text` property if it's mixed content. For non-compact mode, access the `text` property within an element of `type: 'text'`.
Warnings
- breaking Starting from v1.4.0, converting XML to JS will automatically decode the five standard XML entity codes (`&`, `<`, `>`, `"`, `'`) into their respective characters (`&`, `<`, `>`, `"`, `'`). Previously, `&` would remain `&` unless explicitly sanitized. The `{sanitize: true}` option is also deprecated with this change.
- breaking In v1.1.0, the default behavior for CData block indentation in XML output changed. CData blocks are no longer indented by default, which may affect formatting for users who relied on the previous indented output.
- gotcha When converting from a JavaScript object to XML, v1.5.1 introduced support for a simpler syntax where `{a: 'hi'}` can be converted to `<a>hi</a>` directly, instead of requiring `{a: {_text: 'hi'}}`. While this is an improvement, it changes the expected object structure for simple text nodes.
- gotcha The library offers two main modes: 'compact' and 'non-compact'. The 'non-compact' mode is recommended for preserving the exact order of elements, representing all elements as an array of objects under an 'elements' key. The 'compact' mode, while simpler, might merge elements of the same name into a single array property, losing their original ordering relative to other distinct elements.
Install
-
npm install xml-js -
yarn add xml-js -
pnpm add xml-js
Imports
- xml2js
const xml2js = require('xml-js').xml2js;import { xml2js } from 'xml-js'; // Or if using the unified convert object: // import * as convert from 'xml-js'; // const jsObj = convert.xml2js(xmlString); - js2xml
const js2xml = require('xml-js').js2xml;import { js2xml } from 'xml-js'; // Or if using the unified convert object: // import * as convert from 'xml-js'; // const xmlString = convert.js2xml(jsObj); - convert
import convert from 'xml-js';
import * as convert from 'xml-js';
Quickstart
import { xml2js, js2xml } from 'xml-js';
// Example XML string
const xmlString = `
<?xml version="1.0" encoding="UTF-8"?>
<!-- Sample XML Document -->
<bookstore>
<book category="programming">
<title lang="en">Learning XML</title>
<author>John Doe</author>
<price>39.95</price>
</book>
<book category="web">
<title lang="en">HTML & CSS</title>
<author>Jane Smith</author>
<price>29.99</price>
<description><![CDATA[A comprehensive guide to web design.]]></description>
</book>
</bookstore>
`;
// 1. Convert XML to JavaScript object (non-compact, preserving order)
const jsObjectNonCompact = xml2js(xmlString, { compact: false, spaces: 2 });
console.log('--- Non-Compact JS Object ---');
console.log(JSON.stringify(jsObjectNonCompact, null, 2));
// 2. Convert XML to JavaScript object (compact mode)
const jsObjectCompact = xml2js(xmlString, { compact: true, spaces: 2 });
console.log('\n--- Compact JS Object ---');
console.log(JSON.stringify(jsObjectCompact, null, 2));
// 3. Convert JavaScript object back to XML (from compact object)
const xmlOutputFromCompact = js2xml(jsObjectCompact, { compact: true, spaces: 2 });
console.log('\n--- XML Output from Compact JS Object ---');
console.log(xmlOutputFromCompact);
// 4. Convert JavaScript object back to XML (from non-compact object)
const xmlOutputFromNonCompact = js2xml(jsObjectNonCompact, { compact: false, spaces: 2 });
console.log('\n--- XML Output from Non-Compact JS Object ---');
console.log(xmlOutputFromNonCompact);