Package Exports
- xml-js
- xml-js/lib/xml2js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (xml-js) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Convert XML text to Javascript object / JSON text (and vice versa).
Synopsis
Motivation
There are many XML to JavaScript object / JSON converters out there, but could not satisfy the following requirements:
Maintain Order of Sub-elements: I wanted
<a/><b/><a/>
to give output as{"elements":[{"type":"element","name":"a"},{"type":"element","name":"b"},{"type":"element","name":"a"}]}
instead of{a:[{},{}],b:{}}
.Fully XML Compliant: Can parse: Comments, Processing Instructions, XML Declarations, Entity declarations, and CDATA Sections.
Reversible: Whether converting xml→json or json→xml, the result should be convertable to its original form.
Change Property Key Name: Usually output of XML attributes are stored in
@attr
,_atrr
,$attr
,$
, orwhatever
in order to avoid conflicting with name of sub-elements. This library store them inattributes
, but most importantly, you can change this to whatever you like.Portable Code: Written purely in JavaScript (this is default behavior, but this can be slow for very large XML text).
Fast Code (if required): With little effort, the underlying sax engine (based on JavaScript) can be sustituted with node-expat engine (based on VC++).
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).
Support Streaming: ...
Compact vs Non-Compact
Most XML parsers (including online parsers) convert <a/>
to some compact result like {"a":{}}
instead of non-compact result like {"elements":[{"type":"element","name":"a"}]}
.
While this result might work in most cases, there are cases when different elements are mixed inside a parent element: <n><a x="1"/><b x="2"/><a x="3"/></n>
.
In this case, the compact output will be {n:{a:[{_:{x:"1"}},{_:{x:"3"}}],b:{_:{x:"2"}}}}
,
which has merged the second <a/>
with the first <a/>
into an array and so the order is not preserved.
Although non-compact output is more accurate representation of original XML than compact version, the non-compact consumes more space on disk.
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 type.
Usage
Installation
npm install xml-js
You can also installed it globally to use it as command line convertor.
npm install -g 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 output of this code, see the picture above in Synopsis section.
Sample Conversions
XML | JS/JSON compact | JS/JSON non-compact |
---|---|---|
<?xml?> |
{"_declaration":{}} |
{"declaration":{}} |
<?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>"}]} |
<a/> |
{"a":{}} |
{"elements":[{"type":"element","name":"a"}]} |
<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"}}]} |
<a> Hi </a> |
{"a":{"_text":" Hi "}} |
{"elements":[{"type":"element","name":"a","elements":[{"type":"text","text":" Hi "}]}]} |
<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"}]}]} |
API Reference
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');
var options = {ignoreText: 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.
Option | Default | Description |
---|---|---|
spaces |
0 |
Number of spaces to be used for indenting XML output. |
compact |
false |
Whether the input object is in compact form or not. |
fullTagEmptyElement |
false |
Whether to produce element without sub-elements as full tag pairs <a></a> rather than self closing tag </a> . |
ignoreDeclaration |
false |
Whether to ignore writing declaration directives of xml. For example, <?xml?> will be ignored. |
ignoreAttributes |
false |
Whether to ignore writing attributes of the elements. For example, x="1" in <a x="1"></a> will be ignored |
ignoreComment |
false |
Whether to ignore writing comments of the elements. That is, no <!-- --> will be generated. |
ignoreCdata |
false |
Whether to ignore writing CData of the elements. That is, no <![CDATA[ ]]> will be generated. |
ignoreText |
false |
Whether 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');
var options = {ignoreText: 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.
Option | Default | Description |
---|---|---|
compact |
false |
Whether to produce detailed object or compact object. |
trim |
false |
Whether to trim white space characters that may exist before and after the text. |
sanitize |
false |
Whether to replace & < > " ' with & < > " ' respectively in the resultant text. |
nativeType |
false |
whether to attempt converting text of numerals or of boolean values to native type. For example, "123" will be 123 and "true" will be true |
addParent |
false |
Whether to add parent property in each element object that points to parent object. |
alwaysChildren |
false |
Whether to always generate elements property even when there are no actual sub elements. |
ignoreDeclaration |
false |
Whether to ignore writing declaration property. That is, no declaration property will be generated. |
ignoreAttributes |
false |
Whether to ignore writing attributes of elements.That is, no attributes property will be generated. |
ignoreComment |
false |
Whether to ignore writing comments of the elements. That is, no comment will be generated. |
ignoreCdata |
false |
Whether to ignore writing CData of the elements. That is, no cdata will be generated. |
ignoreText |
false |
Whether to ignore writing texts of the elements. That is, no text will be generated. |
The below option is applicable only for xml2json()
function.
Option | Default | Description |
---|---|---|
spaces |
0 |
Number of spaces to be used for indenting JSON output. |
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:
Option | Default | Description |
---|---|---|
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) |
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) |
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","attributes":{}}]} (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","attributes":{}}]} (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","attributes":{}}]} (in non-compact form) |
Note: You probably want to set
{textKey: 'value', cdataKey: 'value', commentKey: 'value'}
for non-compact output to make it more consistent and easier for your client code to go through the contents of text, cdata, and comment.
Command Line
Because any good library should support command line usage, this library is no difference.
As Globally Accessible Command
npm install -g xml-js // install this library globally
xml-js test.json // test.json will be converted to test.xml
xml-js test.xml // test.xml will be converted 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"
}
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 help content.
--version, -v Display 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 instruction <?xml ..?> 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-comment Comments of elements will be ignored.
--trim Whitespaces surrounding texts will be trimmed.
--compact JSON is in compact form.
--sanitize Special xml characters will be replaced with entity codes.
--native-type Text will be converted to native type.
--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.
--comment-key To change the default 'comment' key.
--attributes-key To change the default 'attributes' key.
--declaration-key To change the default 'declaration' key.
--type-key To change the default 'type' key (applicable if --compact is not set).
--cdata-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
Comparison with Other Libraries
xml2js xml2json xml-objects xml-js-converter fast-xml2js co-xml2js xml-simple xml2js-expat
Testing
To perform tests on this project:
cd node_modules/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 or Jasmine test spec where the code is failing.
Contributing
If you want to add a feature or fix a bug, please fork the repository and make the changes in your fork. Add tests to ensure your code is working properly, then submit a pull request.