node-xml2js
===========
Ever had the urge to parse XML? And wanted to access the data in some sane,
easy way? Don't want to compile a C parser, for whatever reason? Then xml2js is
what you're looking for!
Description
===========
Simple XML to JavaScript object converter. It supports bi-directional conversion.
Uses [sax-js](https://github.com/isaacs/sax-js/) and
[xmlbuilder-js](https://github.com/oozcitak/xmlbuilder-js/).
Note: If you're looking for a full DOM parser, you probably want
[JSDom](https://github.com/tmpvar/jsdom).
Installation
============
Simplest way to install `xml2js` is to use [npm](http://npmjs.org), just `npm
install xml2js` which will download xml2js and all dependencies.
xml2js is also available via [Bower](http://bower.io/), just `bower install
xml2js` which will download xml2js and all dependencies.
Usage
=====
No extensive tutorials required because you are a smart developer! The task of
parsing XML should be an easy one, so let's make it so! Here's some examples.
Shoot-and-forget usage
----------------------
You want to parse XML as simple and easy as possible? It's dangerous to go
alone, take this:
```javascript
var parseString = require('xml2js').parseString;
var xml = "<root>Hello xml2js!</root>"
parseString(xml, function (err, result) {
console.dir(result);
});
```
Can't get easier than this, right? This works starting with `xml2js` 0.2.3.
With CoffeeScript it looks like this:
```coffeescript
{parseString} = require 'xml2js'
xml = "<root>Hello xml2js!</root>"
parseString xml, (err, result) ->
console.dir result
```
If you need some special options, fear not, `xml2js` supports a number of
options (see below), you can specify these as second argument:
```javascript
parseString(xml, {trim: true}, function (err, result) {
});
```
Simple as pie usage
-------------------
That's right, if you have been using xml-simple or a home-grown
wrapper, this was added in 0.1.11 just for you:
```javascript
var fs = require('fs'),
xml2js = require('xml2js');
var parser = new xml2js.Parser();
fs.readFile(__dirname + '/foo.xml', function(err, data) {
parser.parseString(data, function (err, result) {
console.dir(result);
console.log('Done');
});
});
```
Look ma, no event listeners!
You can also use `xml2js` from
[CoffeeScript](https://github.com/jashkenas/coffeescript), further reducing
the clutter:
```coffeescript
fs = require 'fs',
xml2js = require 'xml2js'
parser = new xml2js.Parser()
fs.readFile __dirname + '/foo.xml', (err, data) ->
parser.parseString data, (err, result) ->
console.dir result
console.log 'Done.'
```
But what happens if you forget the `new` keyword to create a new `Parser`? In
the middle of a nightly coding session, it might get lost, after all. Worry
not, we got you covered! Starting with 0.2.8 you can also leave it out, in
which case `xml2js` will helpfully add it for you, no bad surprises and
inexplicable bugs!
Promise usage
-------------
```javascript
var xml2js = require('xml2js');
var xml = '<foo></foo>';
// With parser
var parser = new xml2js.Parser(/* options */);
parser.parseStringPromise(data).then(function (result) {
console.dir(result);
console.log('Done');
})
.catch(function (err) {
// Failed
});
// Without parser
xml2js.parseStringPromise(data /*, options */).then(function (result) {
console.dir(result);
console.log('Done');
})
.catch(function (err) {
// Failed
});
```
Parsing multiple files
----------------------
If you want to parse multiple files, you have multiple possibilities:
* You can create one `xml2js.Parser` per file. That's the recommended one
and is promised to always *just work*.
* You can call `reset()` on your parser object.
* You can hope everything goes well anyway. This behaviour is not
guaranteed work always, if ever. Use option #1 if possible. Thanks!
So you wanna some JSON?
-----------------------
Just wrap the `result` object in a call to `JSON.stringify` like this
`JSON.stringify(result)`. You get a string containing the JSON representation
of the parsed object that you can feed to JSON-hungry consumers.
Displaying results
------------------
You might wonder why, using `console.dir` or `console.log` the output at some
level is only `[Object]`. Don't worry, this is not because `xml2js` got lazy.
That's because Node uses `util.inspect` to convert the object into strings and
that function stops after `depth=2` which is a bit low for most XML.
To display the whole deal, you can use `console.log(util.inspect(result, false,
null))`, which displays the whole result.
So much for that, but what if you use
[eyes](https://github.com/cloudhead/eyes.js) for nice colored output and it
truncates the output with `…`? Don't fear, there's also a solution for that,
you just need to increase the `maxLength` limit by creating a custom inspector
`var inspect = require('eyes').inspector({maxLength: false})` and then you can
easily `inspect(result)`.
XML builder usage
-----------------
Since 0.4.0, objects can be also be used to build XML:
```javascript
var xml2js = require('xml2js');
var obj = {name: "Super", Surname: "Man", age: 23};
var builder = new xml2js.Builder();
var xml = builder.buildObject(obj);
```
At the moment, a one to one bi-directional conversion is guaranteed only for
default configuration, except for `attrkey`, `charkey` and `explicitArray` options
you can redefine to your taste. Writing CDATA is supported via setting the `cdata`
option to `true`.
To specify attributes:
```javascript
var xml2js = require('xml2js');
var obj = {root: {$: {id: "my id"}, _: "my inner text"}};
var builder = new xml2js.Builder();
var xml = builder.buildObject(obj);
```
### Adding xmlns attributes
You can generate XML that declares XML namespace prefix / URI pairs with xmlns attributes.
Example declaring a default namespace on the root element:
```javascript
let obj = {
Foo: {
$: {
"xmlns": "http://foo.com"
}
}
};
```
Result of `buildObject(obj)`:
```xml
<Foo xmlns="http://foo.com"/>
```
Example declaring non-default namespaces on non-root elements:
```javascript
let obj = {
'foo:Foo': {
$: {
'xmlns:foo': 'http://foo.com'
},
'bar:Bar': {
$: {
'xmlns:bar': 'http://bar.com'
}
}
}
}
```
Result of `buildObject(obj)`:
```xml
<foo:Foo xmlns:foo="http://foo.com">
<bar:Bar xmlns:bar="http://bar.com"/>
</foo:Foo>
```
Processing attribute, tag names and values
------------------------------------------
Since 0.4.1 you can optionally provide the parser with attribute name and tag name processors as well as element value processors (Since 0.4.14, you can also optionally provide the parser with attribute value processors):
```javascript
function nameToUpperCase(name){
return name.toUpperCase();
}
//transform all attribute and tag names and values to uppercase
parseString(xml, {
tagNameProcessors: [nameToUpperCase],
attrNameProcessors: [nameToUpperCase],
valueProcessors: [nameToUpperCase],
attrValueProcessors: [nameToUpperCase]},
function (err, result) {
// processed data
});
```
The `tagNameProcessors` and `attrNameProcessors` options
accept an `Array` of functions with the following signature:
```javascript
function (name){
//do something with `name`
return name
}
```
The `attrValueProcessors` and `valueProcessors` options
accept an `Array` of functions with the following signature:
```javascript
function (value, name) {
//`name` will be the node name or attribute name
//do something with `value`, (optionally) dependent on the node/attr name
return value
}
```
Some processors are provided out-of-the-box and can be found in `lib/processors.js`:
- `normalize`: transforms the name to lowercase.
(Automatically used when `options.normalize` is set to `true`)
- `firstCharLowerCase`: transforms the first character to lower case.
E.g. 'MyTagName' becomes 'myTagName'
- `stripPrefix`: strips the xml