{"id":12762,"library":"xml-js","title":"XML-JS Converter","description":"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.","status":"active","version":"1.6.11","language":"javascript","source_language":"en","source_url":"https://github.com/nashwaan/xml-js","tags":["javascript","XML","xml","js","JSON","json","cdata","CDATA","doctype","typescript"],"install":[{"cmd":"npm install xml-js","lang":"bash","label":"npm"},{"cmd":"yarn add xml-js","lang":"bash","label":"yarn"},{"cmd":"pnpm add xml-js","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"While CommonJS `require` works, modern Node.js and browser environments typically use ES module `import`. The library can also be imported as a single 'convert' object from which `xml2js` is accessed.","wrong":"const xml2js = require('xml-js').xml2js;","symbol":"xml2js","correct":"import { xml2js } from 'xml-js';\n// Or if using the unified convert object:\n// import * as convert from 'xml-js';\n// const jsObj = convert.xml2js(xmlString);"},{"note":"Similar to xml2js, js2xml can be imported directly or accessed as a method on the main 'convert' export.","wrong":"const js2xml = require('xml-js').js2xml;","symbol":"js2xml","correct":"import { js2xml } from 'xml-js';\n// Or if using the unified convert object:\n// import * as convert from 'xml-js';\n// const xmlString = convert.js2xml(jsObj);"},{"note":"The library primarily uses named exports for its functions. Importing the entire module as 'convert' with `* as` is the correct way to access `convert.xml2js` and `convert.js2xml` methods while maintaining ES module compatibility.","wrong":"import convert from 'xml-js';","symbol":"convert","correct":"import * as convert from 'xml-js';"}],"quickstart":{"code":"import { xml2js, js2xml } from 'xml-js';\n\n// Example XML string\nconst xmlString = `\n  <?xml version=\"1.0\" encoding=\"UTF-8\"?>\n  <!-- Sample XML Document -->\n  <bookstore>\n    <book category=\"programming\">\n      <title lang=\"en\">Learning XML</title>\n      <author>John Doe</author>\n      <price>39.95</price>\n    </book>\n    <book category=\"web\">\n      <title lang=\"en\">HTML &amp; CSS</title>\n      <author>Jane Smith</author>\n      <price>29.99</price>\n      <description><![CDATA[A comprehensive guide to web design.]]></description>\n    </book>\n  </bookstore>\n`;\n\n// 1. Convert XML to JavaScript object (non-compact, preserving order)\nconst jsObjectNonCompact = xml2js(xmlString, { compact: false, spaces: 2 });\nconsole.log('--- Non-Compact JS Object ---');\nconsole.log(JSON.stringify(jsObjectNonCompact, null, 2));\n\n// 2. Convert XML to JavaScript object (compact mode)\nconst jsObjectCompact = xml2js(xmlString, { compact: true, spaces: 2 });\nconsole.log('\\n--- Compact JS Object ---');\nconsole.log(JSON.stringify(jsObjectCompact, null, 2));\n\n// 3. Convert JavaScript object back to XML (from compact object)\nconst xmlOutputFromCompact = js2xml(jsObjectCompact, { compact: true, spaces: 2 });\nconsole.log('\\n--- XML Output from Compact JS Object ---');\nconsole.log(xmlOutputFromCompact);\n\n// 4. Convert JavaScript object back to XML (from non-compact object)\nconst xmlOutputFromNonCompact = js2xml(jsObjectNonCompact, { compact: false, spaces: 2 });\nconsole.log('\\n--- XML Output from Non-Compact JS Object ---');\nconsole.log(xmlOutputFromNonCompact);\n","lang":"typescript","description":"Demonstrates converting an XML string to JavaScript objects in both compact and non-compact modes, then converting these JavaScript objects back into formatted XML strings."},"warnings":[{"fix":"Review existing code that relies on encoded entities remaining encoded after XML to JS conversion. Adapt logic to handle decoded characters directly. The `{sanitize: true}` option should be removed as it has no effect.","message":"Starting from v1.4.0, converting XML to JS will automatically decode the five standard XML entity codes (`&amp;`, `&lt;`, `&gt;`, `&quot;`, `&#39;`) into their respective characters (`&`, `<`, `>`, `\"`, `'`). Previously, `&amp;` would remain `&amp;` unless explicitly sanitized. The `{sanitize: true}` option is also deprecated with this change.","severity":"breaking","affected_versions":">=1.4.0"},{"fix":"If indented CData output is required, explicitly set the `{indentCdata: true}` option when calling `js2xml`.","message":"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.","severity":"breaking","affected_versions":">=1.1.0"},{"fix":"Be aware of this change when constructing JavaScript objects for `js2xml`. Both `{a: 'hi'}` and `{a: {_text: 'hi'}}` should generally work, but the simpler form is now supported for convenience and cleaner output.","message":"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.","severity":"gotcha","affected_versions":">=1.5.1"},{"fix":"For precise XML structure preservation and reversibility, always use `{ compact: false }` for both `xml2js` and `js2xml`. Use `{ compact: true }` only if you understand and accept the simplified, potentially order-losing, JSON structure.","message":"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.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure 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(...)`.","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.","error":"TypeError: xml2js is not a function"},{"fix":"Always 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.","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.","error":"Output XML does not match input structure, elements are reordered or missing."},{"fix":"Consult 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'`.","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.","error":"The 'text' content of an element appears as an empty object or incorrect type."}],"ecosystem":"npm"}