xml-js vs xmlbuilder vs xmlbuilder2
JavaScript XML 处理方案:数据转换与文档构建
xml-jsxmlbuilderxmlbuilder2类似的npm包:

JavaScript XML 处理方案:数据转换与文档构建

xml-js 专注于 XML 与 JSON 之间的双向转换,适合处理数据接口交互。xmlbuilder 是经典的 XML 文档构建库,采用链式 API 生成 XML 树。xmlbuilder2 是 xmlbuilder 的现代重构版,基于 DOM 标准构建,支持更规范的文档操作。三者分别解决了数据格式互换、传统节点构建和现代标准构建的不同需求。

npm下载趋势

3 年

GitHub Stars 排名

统计详情

npm包名称
下载量
Stars
大小
Issues
发布时间
License
xml-js01,339-1278 年前MIT
xmlbuilder0925-86 年前MIT
xmlbuilder20409940 kB3010 个月前MIT

xml-js vs xmlbuilder vs xmlbuilder2: 核心用途与架构差异

在 JavaScript 生态中处理 XML 时,开发者常面临两个不同方向的需求:一是数据格式互换(如 XML 转 JSON),二是程序化构建 XML 文档。xml-js、xmlbuilder 和 xmlbuilder2 分别代表了这三种不同的解决思路。虽然它们都涉及 XML,但底层设计目标完全不同。让我们从实际工程角度对比它们的用法。

🎯 核心定位:数据转换 vs 文档构建

xml-js 的核心任务是数据序列化与反序列化。

  • 它将 XML 字符串转换为 JSON 对象,或将 JSON 对象转换为 XML 字符串。
  • 适合处理 API 响应、配置文件转换,不适合手动构建复杂文档结构。
// xml-js: JSON 转 XML
const convert = require('xml-js');
const json = { declaration: { attributes: { version: '1.0' } }, elements: [{ type: 'element', name: 'root', elements: [{ type: 'text', text: 'hello' }] }] };
const xml = convert.json2xml(json, { compact: false });

xmlbuilder 的核心任务是流式构建 XML 树。

  • 使用链式调用逐个添加节点和属性。
  • 适合生成报表、SOAP 消息等需要精确控制节点顺序的场景。
// xmlbuilder: 链式构建
const builder = require('xmlbuilder');
const xml = builder.create('root')
  .att('version', '1.0')
  .ele('message')
  .txt('hello')
  .end({ pretty: true });

xmlbuilder2 的核心任务是基于 DOM 标准构建。

  • 同样支持链式调用,但底层基于 W3C DOM 规范。
  • 支持更复杂的文档操作,如节点查找、克隆和标准遍历。
// xmlbuilder2: DOM 构建
const { create } = require('xmlbuilder2');
const doc = create().version('1.0').ele('root').att('version', '1.0');
doc.ele('message').txt('hello');
const xml = doc.end({ prettyPrint: true });

🔄 数据读取与解析能力

xml-js 提供直接的双向解析。

  • 输入 XML 字符串,输出 JS 对象。
  • 配置项丰富,可控制是否压缩格式。
// xml-js: XML 转 JSON
const result = convert.xml2json('<root><msg>hello</msg></root>', { compact: true });
// 输出:{ root: { msg: { _text: 'hello' } } }

xmlbuilder 主要专注于写入。

  • 官方 API 不直接支持解析现有 XML 字符串。
  • 若需修改现有 XML,通常需配合其他解析库使用。
// xmlbuilder: 无内置解析 API
// 开发者通常需手动构建新树,无法直接加载旧 XML 进行修改

xmlbuilder2 支持导入现有 XML。

  • 可以解析字符串为 DOM 对象,修改后再导出。
  • 适合需要读取并修改现有文档的场景。
// xmlbuilder2: 导入并修改
const { convert, create } = require('xmlbuilder2');
const doc = convert.xml2js('<root><msg>old</msg></root>');
doc.first().ele('msg').txt('new');
const xml = doc.end({ prettyPrint: true });

📐 标准合规性与扩展性

xml-js 不关心 DOM 标准。

  • 它只关注数据结构的映射。
  • 无法进行节点遍历或 XPath 查询。
// xml-js: 纯数据对象操作
// 无法使用 document.getElementById 等 DOM 方法
const obj = convert.xml2json(xml);
// 只能通过 JS 对象属性访问数据

xmlbuilder 使用自定义树结构。

  • 节点对象是库特定的,非标准 DOM 节点。
  • 扩展性受限,难以与其他 DOM 工具库互操作。
// xmlbuilder: 自定义节点对象
const root = builder.create('root');
// root 不是标准 DOM Element,无法传入需要 DOM 的 API

xmlbuilder2 完全兼容 DOM 标准。

  • 生成的节点是标准 DOM 对象。
  • 可与其他基于 DOM 的库(如 xmldom)配合使用。
// xmlbuilder2: 标准 DOM 节点
const doc = create().ele('root');
const element = doc.first();
// element 符合 DOM 接口,支持标准属性如 tagName, attributes

🛠️ 维护状态与未来支持

xml-js 保持活跃维护。

  • 专注于转换功能,需求稳定。
  • 适合长期用于数据格式兼容层。
// xml-js: 稳定用于转换场景
// 社区持续更新以修复解析边缘情况

xmlbuilder 处于维护模式。

  • 作者已推荐新项目使用 xmlbuilder2。
  • 旧项目可继续使用,但新功能开发不建议依赖。
// xmlbuilder: 遗留项目常用
// 新文档常标注建议迁移至 xmlbuilder2

xmlbuilder2 是当前推荐标准。

  • 持续更新,支持现代 JavaScript 特性(如 ES Modules)。
  • 修复了旧版的性能问题和内存泄漏风险。
// xmlbuilder2: 新项目首选
// 支持 import/export 语法,更适合现代构建工具

📊 功能对比总结

特性xml-jsxmlbuilderxmlbuilder2
主要用途XML <-> JSON 转换构建 XML 树构建 XML 树 (DOM 标准)
解析现有 XML✅ 支持❌ 不支持✅ 支持
DOM 兼容❌ 纯 JSON 对象❌ 自定义对象✅ 标准 DOM 节点
API 风格函数调用链式调用链式调用 + DOM API
维护状态活跃维护模式活跃推荐
适用场景数据接口、配置转换旧项目维护、简单生成新项目、复杂文档操作

💡 最终建议

xml-js 是数据转换的专用工具 🔄。如果你的工作流主要是接收 XML 响应并转为 JSON 处理,或者需要将配置导出为 XML,它是最高效的选择。不要试图用它来构建复杂文档。

xmlbuilder 是历史遗留的经典 🕰️。仅在维护旧代码库时使用。它的 API 简单,但缺乏标准兼容性,且不再作为主要开发重点。

xmlbuilder2 是现代构建的标准答案 🏗️。对于所有新项目,尤其是需要操作文档结构、符合 Web 标准或与其他 DOM 工具集成的场景,应优先选择它。它解决了旧版的架构限制,同时保持了易用性。

核心原则:处理数据用 xml-js,构建文档用 xmlbuilder2,除非被迫维护旧代码,否则避免使用 xmlbuilder。

如何选择: xml-js vs xmlbuilder vs xmlbuilder2

  • xml-js:

    选它如果你需要在 XML 和 JSON 之间频繁转换数据,比如处理遗留系统的接口响应或配置文件,且不需要手动构建复杂的 XML 树结构。

  • xmlbuilder:

    选它如果你正在维护旧项目,或者需要极简单的 XML 生成且不想引入较大的依赖,但需注意它已不再作为首选推荐。

  • xmlbuilder2:

    选它如果你是新项目,需要符合 DOM 标准的 XML 操作,或者需要更好的性能和现代 JavaScript 特性支持,它是 xmlbuilder 的正式继任者。

xml-js的README

XML ⇔ JS/JSON

Convert XML text to Javascript object / JSON text (and vice versa).

Build Status Build Status Build Status

Coverage Status codecov Codacy Badge Code Climate

npm License Downloads/month Dependency Status Package Quality

Synopsis

Convert XML ↔ JS/JSON as compact or non-compact

Features

  • Maintain Order of Elements: Most libraries will convert <a/><b/><a/> to {a:[{},{}],b:{}} which merges any node of same name into an array. This library can create the following to preserve the order of elements: {"elements":[{"type":"element","name":"a"},{"type":"element","name":"b"},{"type":"element","name":"a"}]}.

This is very important and it is the main reason why this library was created. Read also Compact vs Non-Compact for more info.

  • Fully XML Compliant: Can parse: elements, attributes, texts, comments, CData, DOCTYPE, XML declarations, and Processing Instructions.

  • Reversible: Whether converting xml→json or json→xml, the result can be converted back to its original form.

  • Minimal Dependencies: This library depends only on one external npm module.

  • Change Property Key Name: Usually output of XML attributes are stored in @attr, _atrr, $attr or $ in order to avoid conflicting with name of sub-elements. This library store them in attributes, but most importantly, you can change this to whatever you like.

  • Support Upwards Traversal: By setting {addParent: true} option, an extra property named parent will be generated along each element so that its parent can be referenced. Therefore, anywhere during the traversal of an element, its children and its parent can be easily accessed.

  • Support Command Line: To quickly convert xml or json files, this module can be installed globally or locally (i.e. use it as script in package.json).

  • Customize Processing using Callback Hooks: Custom functions can be supplied to do additional processing for different parts of xml or json (like cdata, comments, elements, attributes ...etc).

  • Portable Code: Written purely in JavaScript which means it can be used in Node environment and browser environment (via bundlers like browserify/JSPM/Webpack).

  • Typings Info Included: Support type checking and code suggestion via intellisense. Thanks to the wonderful efforts by DenisCarriere.

Compact vs Non-Compact

Most XML to JSON converters (including online converters) convert <a/> to some compact output like {"a":{}} instead of non-compact output like {"elements":[{"type":"element","name":"a"}]}.

While compact output might work in most situations, there are cases when elements of different names are mixed inside a parent element. Lets use <a x="1"/><b x="2"/><a x="3"/> as an example. Most converters will produce compact output like this {a:[{_:{x:"1"}},{_:{x:"3"}}], b:{_:{x:"2"}}}, which has merged both <a> elements into an array. If you try to convert this back to xml, you will get <a x="1"/><a x="3"/><b x="2"/> which has not preserved the order of elements!

The reason behind this behavior is due to the inherent limitation in the compact representation. Because output like {a:{_:{x:"1"}}, b:{_:{x:"2"}}, a:{_:{x:"3"}}} is illegal (same property name a should not appear twice in an object). This leaves no option but to use array {a:[{_:{x:"1"}},{_:{x:"3"}}].

The non-compact output, which is supported by this library, will produce more information and always guarantees the order of the elements as they appeared in the XML file.

Another drawback of compact output is the resultant element can be an object or an array and therefore makes the client code a little awkward in terms of the extra check needed on object type before processing.

NOTE: Although non-compact output is more accurate representation of original XML than compact version, the non-compact version is verbose and consumes more space. This library provides both options. Use {compact: false} if you are not sure because it preserves everything; otherwise use {compact: true} if you want to save space and you don't care about mixing elements of same name and losing their order.

Tip: You can reduce the output size by using shorter key names.

Usage

Installation

npm install --save xml-js

You can also install it globally to use it as a command line convertor (see Command Line).

npm install --global xml-js

Quick start

var convert = require('xml-js');
var xml =
'<?xml version="1.0" encoding="utf-8"?>' +
'<note importance="high" logged="true">' +
'    <title>Happy</title>' +
'    <todo>Work</todo>' +
'    <todo>Play</todo>' +
'</note>';
var result1 = convert.xml2json(xml, {compact: true, spaces: 4});
var result2 = convert.xml2json(xml, {compact: false, spaces: 4});
console.log(result1, '\n', result2);

To see the result of this code, see the output above in Synopsis section.

Or run and edit this code live in the browser.

Sample Conversions

XMLJS/JSON compactJS/JSON non-compact
<a/>{"a":{}}{"elements":[{"type":"element","name":"a"}]}
<a/><b/>{"a":{},"b":{}}{"elements":[{"type":"element","name":"a"},{"type":"element","name":"b"}]}
<a><b/></a>{"a":{"b":{}}}{"elements":[{"type":"element","name":"a","elements":[{"type":"element","name":"b"}]}]}
<a> Hi </a>{"a":{"_text":" Hi "}}{"elements":[{"type":"element","name":"a","elements":[{"type":"text","text":" Hi "}]}]}
<a x="1.234" y="It's"/>{"a":{"_attributes":{"x":"1.234","y":"It's"}}}{"elements":[{"type":"element","name":"a","attributes":{"x":"1.234","y":"It's"}}]}
<?xml?>{"_declaration":{}}{"declaration":{}}
<?go there?>{"_instruction":{"go":"there"}}{"elements":[{"type":"instruction","name":"go","instruction":"there"}]}
<?xml version="1.0" encoding="utf-8"?>{"_declaration":{"_attributes":{"version":"1.0","encoding":"utf-8"}}}{"declaration":{"attributes":{"version":"1.0","encoding":"utf-8"}}}
<!--Hello, World!-->{"_comment":"Hello, World!"}{"elements":[{"type":"comment","comment":"Hello, World!"}]}
<![CDATA[<foo></bar>]]>{"_cdata":"<foo></bar>"}{"elements":[{"type":"cdata","cdata":"<foo></bar>"}]}

API Reference

This library provides 4 functions: js2xml(), json2xml(), xml2js(), and xml2json(). Here are the usages for each one (see more details in the following sections):

var convert = require('xml-js');
result = convert.js2xml(js, options);     // to convert javascript object to xml text
result = convert.json2xml(json, options); // to convert json text to xml text
result = convert.xml2js(xml, options);    // to convert xml text to javascript object
result = convert.xml2json(xml, options);  // to convert xml text to json text

Convert JS object / JSON → XML

To convert JavaScript object to XML text, use js2xml(). To convert JSON text to XML text, use json2xml().

var convert = require('xml-js');
var json = require('fs').readFileSync('test.json', 'utf8');
var options = {compact: true, ignoreComment: true, spaces: 4};
var result = convert.json2xml(json, options);
console.log(result);

Options for Converting JS object / JSON → XML

The below options are applicable for both js2xml() and json2xml() functions.

OptionDefaultDescription
spaces0Number of spaces to be used for indenting XML output. Passing characters like ' ' or '\t' are also accepted.
compactfalseWhether the input object is in compact form or not. By default, input is expected to be in non-compact form.
IMPORTANT: Remeber to set this option compact: true if you are supplying normal json (which is likely equivalent to compact form). Otherwise, the function assumes your json input is non-compact form and you will not get a result if it is not in that form. See Synopsis to know the difference between the two json forms
fullTagEmptyElementfalseWhether to produce element without sub-elements as full tag pairs <a></a> rather than self closing tag <a/>.
indentCdatafalseWhether to write CData in a new line and indent it. Will generate <a>\n <![CDATA[foo]]></a> instead of <a><![CDATA[foo]]></a>. See discussion
indentAttributesfalseWhether to print attributes across multiple lines and indent them (when spaces is not 0). See example.
ignoreDeclarationfalseWhether to ignore writing declaration directives of xml. For example, <?xml?> will be ignored.
ignoreInstructionfalseWhether to ignore writing processing instruction of xml. For example, <?go there?> will be ignored.
ignoreAttributesfalseWhether to ignore writing attributes of the elements. For example, x="1" in <a x="1"></a> will be ignored
ignoreCommentfalseWhether to ignore writing comments of the elements. That is, no <!-- --> will be generated.
ignoreCdatafalseWhether to ignore writing CData of the elements. That is, no <![CDATA[ ]]> will be generated.
ignoreDoctypefalseWhether to ignore writing Doctype of the elements. That is, no <!DOCTYPE > will be generated.
ignoreTextfalseWhether to ignore writing texts of the elements. For example, hi text in <a>hi</a> will be ignored.

Convert XML → JS object / JSON

To convert XML text to JavaScript object, use xml2js(). To convert XML text to JSON text, use xml2json().

var convert = require('xml-js');
var xml = require('fs').readFileSync('test.xml', 'utf8');
var options = {ignoreComment: true, alwaysChildren: true};
var result = convert.xml2js(xml, options); // or convert.xml2json(xml, options)
console.log(result);

Options for Converting XML → JS object / JSON

The below options are applicable for both xml2js() and xml2json() functions.

OptionDefaultDescription
compactfalseWhether to produce detailed object or compact object.
trimfalseWhether to trim whitespace characters that may exist before and after the text.
sanitize (Deprecated)falseWhether to replace & < > with &amp; &lt; &gt; respectively, in the resultant text.
nativeTypefalseWhether to attempt converting text of numerals or of boolean values to native type. For example, "123" will be 123 and "true" will be true
nativeTypeAttributesfalseWhether to attempt converting attributes of numerals or of boolean values to native type. See also nativeType above.
addParentfalseWhether to add parent property in each element object that points to parent object.
alwaysArrayfalseWhether to always put sub element, even if it is one only, as an item inside an array. <a><b/></a> will be a:[{b:[{}]}] rather than a:{b:{}} (applicable for compact output only). If the passed value is an array, only elements with names in the passed array are always made arrays.
alwaysChildrenfalseWhether to always generate elements property even when there are no actual sub elements. <a></a> will be {"elements":[{"type":"element","name":"a","elements":[]}]} rather than {"elements":[{"type":"element","name":"a"}]} (applicable for non-compact output).
instructionHasAttributesfalseWhether to parse contents of Processing Instruction as attributes or not. <?go to="there"?> will be {"_instruction":{"go":{"_attributes":{"to":"there"}}}} rather than {"_instruction":{"go":"to=\"there\""}}. See discussion.
ignoreDeclarationfalseWhether to ignore parsing declaration property. That is, no declaration property will be generated.
ignoreInstructionfalseWhether to ignore parsing processing instruction property. That is, no instruction property will be generated.
ignoreAttributesfalseWhether to ignore parsing attributes of elements.That is, no attributes property will be generated.
ignoreCommentfalseWhether to ignore parsing comments of the elements. That is, no comment will be generated.
ignoreCdatafalseWhether to ignore parsing CData of the elements. That is, no cdata will be generated.
ignoreDoctypefalseWhether to ignore parsing Doctype of the elements. That is, no doctype will be generated.
ignoreTextfalseWhether to ignore parsing texts of the elements. That is, no text will be generated.

The below option is applicable only for xml2json() function.

OptionDefaultDescription
spaces0Number of spaces to be used for indenting JSON output. Passing characters like ' ' or '\t' are also accepted.

Options for Changing Key Names

To change default key names in the output object or the default key names assumed in the input JavaScript object / JSON, use the following options:

OptionDefaultDescription
declarationKey"declaration" or "_declaration"Name of the property key which will be used for the declaration. For example, if declarationKey: '$declaration' then output of <?xml?> will be {"$declaration":{}} (in compact form)
instructionKey"instruction" or "_instruction"Name of the property key which will be used for the processing instruction. For example, if instructionKey: '$instruction' then output of <?go there?> will be {"$instruction":{"go":"there"}} (in compact form)
attributesKey"attributes" or "_attributes"Name of the property key which will be used for the attributes. For example, if attributesKey: '$attributes' then output of <a x="hello"/> will be {"a":{$attributes:{"x":"hello"}}} (in compact form)
textKey"text" or "_text"Name of the property key which will be used for the text. For example, if textKey: '$text' then output of <a>hi</a> will be {"a":{"$text":"Hi"}} (in compact form)
cdataKey"cdata" or "_cdata"Name of the property key which will be used for the cdata. For example, if cdataKey: '$cdata' then output of <![CDATA[1 is < 2]]> will be {"$cdata":"1 is < 2"} (in compact form)
doctypeKey"doctype" or "_doctype"Name of the property key which will be used for the doctype. For example, if doctypeKey: '$doctype' then output of <!DOCTYPE foo> will be {"$doctype":" foo} (in compact form)
commentKey"comment" or "_comment"Name of the property key which will be used for the comment. For example, if commentKey: '$comment' then output of <!--note--> will be {"$comment":"note"} (in compact form)
parentKey"parent" or "_parent"Name of the property key which will be used for the parent. For example, if parentKey: '$parent' then output of <a></b></a> will be {"a":{"b":{$parent:_points_to_a}}} (in compact form)
typeKey"type"Name of the property key which will be used for the type. For example, if typeKey: '$type' then output of <a></a> will be {"elements":[{"$type":"element","name":"a"}]} (in non-compact form)
nameKey"name"Name of the property key which will be used for the name. For example, if nameKey: '$name' then output of <a></a> will be {"elements":[{"type":"element","$name":"a"}]} (in non-compact form)
elementsKey"elements"Name of the property key which will be used for the elements. For example, if elementsKey: '$elements' then output of <a></a> will be {"$elements":[{"type":"element","name":"a"}]} (in non-compact form)

Two default values mean the first is used for non-compact output and the second is for compact output.

TIP: In compact mode, you can further reduce output result by using fewer characters for key names {textKey: '_', attributesKey: '$', commentKey: 'value'}. This is also applicable to non-compact mode.

TIP: In non-compact mode, you probably want to set {textKey: 'value', cdataKey: 'value', commentKey: 'value'} to make it more consistent and easier for your client code to go through the contents of text, cdata, and comment.

Options for Custom Processing Functions

For XML → JS object / JSON, following custom callback functions can be supplied:

var convert = require('xml-js');
var xml = '<foo:Name>Ali</Name> <bar:Age>30</bar:Age>';
var options = {compact: true, elementNameFn: function(val) {return val.replace('foo:','').toUpperCase();}};
var result = convert.xml2json(xml, options);
console.log(result); // {"NAME":{"_text":"Ali"},"BAR:AGE":{"_text":"30"}}
OptionSignatureDescription
doctypeFn(value, parentElement)To perform additional processing for DOCTYPE. For example, {doctypeFn: function(val) {return val.toUpperCase();}}
instructionFn(instructionValue, instructionName, parentElement)To perform additional processing for content of Processing Instruction value. For example, {instructionFn: function(val) {return val.toUpperCase();}}. Note: instructionValue will be an object if instructionHasAttributes is enabled.
cdataFn(value, parentElement)To perform additional processing for CData. For example, {cdataFn: function(val) {return val.toUpperCase();}}.
commentFn(value, parentElement)To perform additional processing for comments. For example, {commentFn: function(val) {return val.toUpperCase();}}.
textFn(value, parentElement)To perform additional processing for texts inside elements. For example, {textFn: function(val) {return val.toUpperCase();}}.
instructionNameFn(instructionName, instructionValue, parentElement)To perform additional processing for Processing Instruction name. For example, {instructionNameFn: function(val) {return val.toUpperCase();}}. Note: instructionValue will be an object if instructionHasAttributes is enabled.
elementNameFn(value, parentElement)To perform additional processing for element name. For example, {elementNameFn: function(val) {return val.toUpperCase();}}.
attributeNameFn(attributeName, attributeValue, parentElement)To perform additional processing for attribute name. For example, {attributeNameFn: function(val) {return val.toUpperCase();}}.
attributeValueFn(attributeValue, attributeName, parentElement)To perform additional processing for attributeValue. For example, {attributeValueFn: function(val) {return val.toUpperCase();}}.
attributesFn(value, parentElement)To perform additional processing for attributes object. For example, {attributesFn: function(val) {return val.toUpperCase();}}.

For JS object / JSON → XML, following custom callback functions can be supplied:

var convert = require('xml-js');
var json = '{"name":{"_text":"Ali"},"age":{"_text":"30"}}';
var options = {compact: true, textFn: function(val, elementName) {return elementName === 'age'? val + '';}};
var result = convert.json2xml(json, options);
console.log(result); // <foo:Name>Ali</Name> <bar:Age>30</bar:Age>
OptionSignatureDescription
doctypeFn(value, currentElementName, currentElementObj)To perform additional processing for DOCTYPE. For example, {doctypeFn: function(val) {return val.toUpperCase();}.
instructionFn(instructionValue, instructionName, currentElementName, currentElementObj)To perform additional processing for content of Processing Instruction value. For example, {instructionFn: function(val) {return val.toUpperCase();}}. Note: instructionValue will be an object if instructionHasAttributes is enabled.
cdataFn(value, currentElementName, currentElementObj)To perform additional processing for CData. For example, {cdataFn: function(val) {return val.toUpperCase();}}.
commentFn(value, currentElementName, currentElementObj)To perform additional processing for comments. For example, {commentFn: function(val) {return val.toUpperCase();}}.
textFn(value, currentElementName, currentElementObj)To perform additional processing for texts inside elements. For example, {textFn: function(val) {return val.toUpperCase();}}.
instructionNameFn(instructionName, instructionValue, currentElementName, currentElementObj)To perform additional processing for Processing Instruction name. For example, {instructionNameFn: function(val) {return val.toUpperCase();}}. Note: instructionValue will be an object if instructionHasAttributes is enabled.
elementNameFn(value, currentElementName, currentElementObj)To perform additional processing for element name. For example, {elementNameFn: function(val) {return val.toUpperCase();}}.
attributeNameFn(attributeName, attributeValue, currentElementName, currentElementObj)To perform additional processing for attribute name. For example, {attributeNameFn: function(val) {return val.toUpperCase();}}.
attributeValueFn(attributeValue, attributeName, currentElementName, currentElementObj)To perform additional processing for attributeValue. For example, {attributeValueFn: function(val) {return val.toUpperCase();}}.
attributesFn(value, currentElementName, currentElementObj)To perform additional processing for attributes object. For example, {attributesFn: function(val) {return val.toUpperCase();}}.
fullTagEmptyElementFn(currentElementName, currentElementObj)Whether to generate full tag or just self closing tag for elements that has no sub elements. For example, {fullTagEmptyElementFn: function(val) {return val === 'foo'}}.

Command Line

Because any good library should support command line usage, this library is no different.

As Globally Accessible Command

npm install -g xml-js                       // install this library globally
xml-js test.json --spaces 4                 // xml result will be printed on screen
xml-js test.json --spaces 4 --out test.xml  // xml result will be saved to test.xml
xml-js test.xml --spaces 4                  // json result will be printed on screen
xml-js test.xml --spaces 4 --out test.json  // json result will be saved to test.json

As Locally Accessible Command

If you want to use it as script in package.json (can also be helpful in task automation via npm scripts)

npm install --save xml-js   // no need to install this library globally

In package.json, write a script:

...
  "dependencies": {
    "xml-js": "latest"
  },
  "scripts": {
    "convert": "xml-js test.json --spaces 4"
  }

Now in the command line, you can run this script by typing:

npm run convert             // task 'scripts.convert' will be executed

CLI Arguments

Usage: xml-js src [options]

  src                  Input file that need to be converted.
                       Conversion type xml->json or json->xml will be inferred from file extension.

Options:
  --help, -h           Display this help content.
  --version, -v        Display version number of this module.
  --out                Output file where result should be written.
  --spaces             Specifies amount of space indentation in the output.
  --full-tag           XML elements will always be in <a></a> form.
  --no-decl            Declaration directive <?xml?> will be ignored.
  --no-inst            Processing instruction <?...?> will be ignored.
  --no-attr            Attributes of elements will be ignored.
  --no-text            Texts of elements will be ignored.
  --no-cdata           CData of elements will be ignored.
  --no-doctype         DOCTYPE of elements will be ignored.
  --no-comment         Comments of elements will be ignored.
  --trim               Any whitespaces surrounding texts will be trimmed.
  --compact            JSON is in compact form.
  --native-type        Numbers and boolean will be converted (coerced) to native type instead of text.
  --always-array       Every element will always be an array type (applicable if --compact is set).
  --always-children    Every element will always contain sub-elements (applicable if --compact is not set).
  --text-key           To change the default 'text' key.
  --cdata-key          To change the default 'cdata' key.
  --doctype-key        To change the default 'doctype' key.
  --comment-key        To change the default 'comment' key.
  --attributes-key     To change the default 'attributes' key.
  --declaration-key    To change the default 'declaration' key.
  --instruction-key    To change the default 'processing instruction' key.
  --type-key           To change the default 'type' key (applicable if --compact is not set).
  --name-key           To change the default 'name' key (applicable if --compact is not set).
  --elements-key       To change the default 'elements' key (applicable if --compact is not set).

Contribution

Testing

To perform tests on this project, download the full repository from GitHub (not from npm) and then do the following:

cd xml-js
npm install
npm test

For live testing, use npm start instead of npm test.

Reporting

Use this link to report an issue or bug. Please include a sample code where the code is failing.

License

MIT