UNPKG

18.3 kBMarkdownView Raw
1node-xml2js
2===========
3
4Ever had the urge to parse XML? And wanted to access the data in some sane,
5easy way? Don't want to compile a C parser, for whatever reason? Then xml2js is
6what you're looking for!
7
8Description
9===========
10
11Simple XML to JavaScript object converter. It supports bi-directional conversion.
12Uses [sax-js](https://github.com/isaacs/sax-js/) and
13[xmlbuilder-js](https://github.com/oozcitak/xmlbuilder-js/).
14
15Note: If you're looking for a full DOM parser, you probably want
16[JSDom](https://github.com/tmpvar/jsdom).
17
18Installation
19============
20
21Simplest way to install `xml2js` is to use [npm](http://npmjs.org), just `npm
22install xml2js` which will download xml2js and all dependencies.
23
24xml2js is also available via [Bower](http://bower.io/), just `bower install
25xml2js` which will download xml2js and all dependencies.
26
27Usage
28=====
29
30No extensive tutorials required because you are a smart developer! The task of
31parsing XML should be an easy one, so let's make it so! Here's some examples.
32
33Shoot-and-forget usage
34----------------------
35
36You want to parse XML as simple and easy as possible? It's dangerous to go
37alone, take this:
38
39```javascript
40var parseString = require('xml2js').parseString;
41var xml = "<root>Hello xml2js!</root>"
42parseString(xml, function (err, result) {
43 console.dir(result);
44});
45```
46
47Can't get easier than this, right? This works starting with `xml2js` 0.2.3.
48With CoffeeScript it looks like this:
49
50```coffeescript
51{parseString} = require 'xml2js'
52xml = "<root>Hello xml2js!</root>"
53parseString xml, (err, result) ->
54 console.dir result
55```
56
57If you need some special options, fear not, `xml2js` supports a number of
58options (see below), you can specify these as second argument:
59
60```javascript
61parseString(xml, {trim: true}, function (err, result) {
62});
63```
64
65Simple as pie usage
66-------------------
67
68That's right, if you have been using xml-simple or a home-grown
69wrapper, this was added in 0.1.11 just for you:
70
71```javascript
72var fs = require('fs'),
73 xml2js = require('xml2js');
74
75var parser = new xml2js.Parser();
76fs.readFile(__dirname + '/foo.xml', function(err, data) {
77 parser.parseString(data, function (err, result) {
78 console.dir(result);
79 console.log('Done');
80 });
81});
82```
83
84Look ma, no event listeners!
85
86You can also use `xml2js` from
87[CoffeeScript](https://github.com/jashkenas/coffeescript), further reducing
88the clutter:
89
90```coffeescript
91fs = require 'fs',
92xml2js = require 'xml2js'
93
94parser = new xml2js.Parser()
95fs.readFile __dirname + '/foo.xml', (err, data) ->
96 parser.parseString data, (err, result) ->
97 console.dir result
98 console.log 'Done.'
99```
100
101But what happens if you forget the `new` keyword to create a new `Parser`? In
102the middle of a nightly coding session, it might get lost, after all. Worry
103not, we got you covered! Starting with 0.2.8 you can also leave it out, in
104which case `xml2js` will helpfully add it for you, no bad surprises and
105inexplicable bugs!
106
107Promise usage
108-------------
109
110```javascript
111var xml2js = require('xml2js');
112var xml = '<foo></foo>';
113
114// With parser
115var parser = new xml2js.Parser(/* options */);
116parser.parseStringPromise(xml).then(function (result) {
117 console.dir(result);
118 console.log('Done');
119})
120.catch(function (err) {
121 // Failed
122});
123
124// Without parser
125xml2js.parseStringPromise(xml /*, options */).then(function (result) {
126 console.dir(result);
127 console.log('Done');
128})
129.catch(function (err) {
130 // Failed
131});
132```
133
134Parsing multiple files
135----------------------
136
137If you want to parse multiple files, you have multiple possibilities:
138
139 * You can create one `xml2js.Parser` per file. That's the recommended one
140 and is promised to always *just work*.
141 * You can call `reset()` on your parser object.
142 * You can hope everything goes well anyway. This behaviour is not
143 guaranteed work always, if ever. Use option #1 if possible. Thanks!
144
145So you wanna some JSON?
146-----------------------
147
148Just wrap the `result` object in a call to `JSON.stringify` like this
149`JSON.stringify(result)`. You get a string containing the JSON representation
150of the parsed object that you can feed to JSON-hungry consumers.
151
152Displaying results
153------------------
154
155You might wonder why, using `console.dir` or `console.log` the output at some
156level is only `[Object]`. Don't worry, this is not because `xml2js` got lazy.
157That's because Node uses `util.inspect` to convert the object into strings and
158that function stops after `depth=2` which is a bit low for most XML.
159
160To display the whole deal, you can use `console.log(util.inspect(result, false,
161null))`, which displays the whole result.
162
163So much for that, but what if you use
164[eyes](https://github.com/cloudhead/eyes.js) for nice colored output and it
165truncates the output with `…`? Don't fear, there's also a solution for that,
166you just need to increase the `maxLength` limit by creating a custom inspector
167`var inspect = require('eyes').inspector({maxLength: false})` and then you can
168easily `inspect(result)`.
169
170XML builder usage
171-----------------
172
173Since 0.4.0, objects can be also be used to build XML:
174
175```javascript
176var xml2js = require('xml2js');
177
178var obj = {name: "Super", Surname: "Man", age: 23};
179
180var builder = new xml2js.Builder();
181var xml = builder.buildObject(obj);
182```
183will result in:
184
185```xml
186<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
187<root>
188 <name>Super</name>
189 <Surname>Man</Surname>
190 <age>23</age>
191</root>
192```
193
194At the moment, a one to one bi-directional conversion is guaranteed only for
195default configuration, except for `attrkey`, `charkey` and `explicitArray` options
196you can redefine to your taste. Writing CDATA is supported via setting the `cdata`
197option to `true`.
198
199To specify attributes:
200```javascript
201var xml2js = require('xml2js');
202
203var obj = {root: {$: {id: "my id"}, _: "my inner text"}};
204
205var builder = new xml2js.Builder();
206var xml = builder.buildObject(obj);
207```
208will result in:
209```xml
210<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
211<root id="my id">my inner text</root>
212```
213
214### Adding xmlns attributes
215
216You can generate XML that declares XML namespace prefix / URI pairs with xmlns attributes.
217
218Example declaring a default namespace on the root element:
219
220```javascript
221let obj = {
222 Foo: {
223 $: {
224 "xmlns": "http://foo.com"
225 }
226 }
227};
228```
229Result of `buildObject(obj)`:
230```xml
231<Foo xmlns="http://foo.com"/>
232```
233Example declaring non-default namespaces on non-root elements:
234```javascript
235let obj = {
236 'foo:Foo': {
237 $: {
238 'xmlns:foo': 'http://foo.com'
239 },
240 'bar:Bar': {
241 $: {
242 'xmlns:bar': 'http://bar.com'
243 }
244 }
245 }
246}
247```
248Result of `buildObject(obj)`:
249```xml
250<foo:Foo xmlns:foo="http://foo.com">
251 <bar:Bar xmlns:bar="http://bar.com"/>
252</foo:Foo>
253```
254
255
256Processing attribute, tag names and values
257------------------------------------------
258
259Since 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):
260
261```javascript
262
263function nameToUpperCase(name){
264 return name.toUpperCase();
265}
266
267//transform all attribute and tag names and values to uppercase
268parseString(xml, {
269 tagNameProcessors: [nameToUpperCase],
270 attrNameProcessors: [nameToUpperCase],
271 valueProcessors: [nameToUpperCase],
272 attrValueProcessors: [nameToUpperCase]},
273 function (err, result) {
274 // processed data
275});
276```
277
278The `tagNameProcessors` and `attrNameProcessors` options
279accept an `Array` of functions with the following signature:
280
281```javascript
282function (name){
283 //do something with `name`
284 return name
285}
286```
287
288The `attrValueProcessors` and `valueProcessors` options
289accept an `Array` of functions with the following signature:
290
291```javascript
292function (value, name) {
293 //`name` will be the node name or attribute name
294 //do something with `value`, (optionally) dependent on the node/attr name
295 return value
296}
297```
298
299Some processors are provided out-of-the-box and can be found in `lib/processors.js`:
300
301- `normalize`: transforms the name to lowercase.
302(Automatically used when `options.normalize` is set to `true`)
303
304- `firstCharLowerCase`: transforms the first character to lower case.
305E.g. 'MyTagName' becomes 'myTagName'
306
307- `stripPrefix`: strips the xml namespace prefix. E.g `<foo:Bar/>` will become 'Bar'.
308(N.B.: the `xmlns` prefix is NOT stripped.)
309
310- `parseNumbers`: parses integer-like strings as integers and float-like strings as floats
311E.g. "0" becomes 0 and "15.56" becomes 15.56
312
313- `parseBooleans`: parses boolean-like strings to booleans
314E.g. "true" becomes true and "False" becomes false
315
316Options
317=======
318
319Apart from the default settings, there are a number of options that can be
320specified for the parser. Options are specified by ``new Parser({optionName:
321value})``. Possible options are:
322
323 * `attrkey` (default: `$`): Prefix that is used to access the attributes.
324 Version 0.1 default was `@`.
325 * `charkey` (default: `_`): Prefix that is used to access the character
326 content. Version 0.1 default was `#`.
327 * `explicitCharkey` (default: `false`) Determines whether or not to use
328 a `charkey` prefix for elements with no attributes.
329 * `trim` (default: `false`): Trim the whitespace at the beginning and end of
330 text nodes.
331 * `normalizeTags` (default: `false`): Normalize all tag names to lowercase.
332 * `normalize` (default: `false`): Trim whitespaces inside text nodes.
333 * `explicitRoot` (default: `true`): Set this if you want to get the root
334 node in the resulting object.
335 * `emptyTag` (default: `''`): what will the value of empty nodes be. In case
336 you want to use an empty object as a default value, it is better to provide a factory
337 function `() => ({})` instead. Without this function a plain object would
338 become a shared reference across all occurrences with unwanted behavior.
339 * `explicitArray` (default: `true`): Always put child nodes in an array if
340 true; otherwise an array is created only if there is more than one.
341 * `ignoreAttrs` (default: `false`): Ignore all XML attributes and only create
342 text nodes.
343 * `mergeAttrs` (default: `false`): Merge attributes and child elements as
344 properties of the parent, instead of keying attributes off a child
345 attribute object. This option is ignored if `ignoreAttrs` is `true`.
346 * `validator` (default `null`): You can specify a callable that validates
347 the resulting structure somehow, however you want. See unit tests
348 for an example.
349 * `xmlns` (default `false`): Give each element a field usually called '$ns'
350 (the first character is the same as attrkey) that contains its local name
351 and namespace URI.
352 * `explicitChildren` (default `false`): Put child elements to separate
353 property. Doesn't work with `mergeAttrs = true`. If element has no children
354 then "children" won't be created. Added in 0.2.5.
355 * `childkey` (default `$$`): Prefix that is used to access child elements if
356 `explicitChildren` is set to `true`. Added in 0.2.5.
357 * `preserveChildrenOrder` (default `false`): Modifies the behavior of
358 `explicitChildren` so that the value of the "children" property becomes an
359 ordered array. When this is `true`, every node will also get a `#name` field
360 whose value will correspond to the XML nodeName, so that you may iterate
361 the "children" array and still be able to determine node names. The named
362 (and potentially unordered) properties are also retained in this
363 configuration at the same level as the ordered "children" array. Added in
364 0.4.9.
365 * `charsAsChildren` (default `false`): Determines whether chars should be
366 considered children if `explicitChildren` is on. Added in 0.2.5.
367 * `includeWhiteChars` (default `false`): Determines whether whitespace-only
368 text nodes should be included. Added in 0.4.17.
369 * `async` (default `false`): Should the callbacks be async? This *might* be
370 an incompatible change if your code depends on sync execution of callbacks.
371 Future versions of `xml2js` might change this default, so the recommendation
372 is to not depend on sync execution anyway. Added in 0.2.6.
373 * `strict` (default `true`): Set sax-js to strict or non-strict parsing mode.
374 Defaults to `true` which is *highly* recommended, since parsing HTML which
375 is not well-formed XML might yield just about anything. Added in 0.2.7.
376 * `attrNameProcessors` (default: `null`): Allows the addition of attribute
377 name processing functions. Accepts an `Array` of functions with following
378 signature:
379 ```javascript
380 function (name){
381 //do something with `name`
382 return name
383 }
384 ```
385 Added in 0.4.14
386 * `attrValueProcessors` (default: `null`): Allows the addition of attribute
387 value processing functions. Accepts an `Array` of functions with following
388 signature:
389 ```javascript
390 function (value, name){
391 //do something with `name`
392 return name
393 }
394 ```
395 Added in 0.4.1
396 * `tagNameProcessors` (default: `null`): Allows the addition of tag name
397 processing functions. Accepts an `Array` of functions with following
398 signature:
399 ```javascript
400 function (name){
401 //do something with `name`
402 return name
403 }
404 ```
405 Added in 0.4.1
406 * `valueProcessors` (default: `null`): Allows the addition of element value
407 processing functions. Accepts an `Array` of functions with following
408 signature:
409 ```javascript
410 function (value, name){
411 //do something with `name`
412 return name
413 }
414 ```
415 Added in 0.4.6
416
417Options for the `Builder` class
418-------------------------------
419These options are specified by ``new Builder({optionName: value})``.
420Possible options are:
421
422 * `attrkey` (default: `$`): Prefix that is used to access the attributes.
423 Version 0.1 default was `@`.
424 * `charkey` (default: `_`): Prefix that is used to access the character
425 content. Version 0.1 default was `#`.
426 * `rootName` (default `root` or the root key name): root element name to be used in case
427 `explicitRoot` is `false` or to override the root element name.
428 * `renderOpts` (default `{ 'pretty': true, 'indent': ' ', 'newline': '\n' }`):
429 Rendering options for xmlbuilder-js.
430 * pretty: prettify generated XML
431 * indent: whitespace for indentation (only when pretty)
432 * newline: newline char (only when pretty)
433 * `xmldec` (default `{ 'version': '1.0', 'encoding': 'UTF-8', 'standalone': true }`:
434 XML declaration attributes.
435 * `xmldec.version` A version number string, e.g. 1.0
436 * `xmldec.encoding` Encoding declaration, e.g. UTF-8
437 * `xmldec.standalone` standalone document declaration: true or false
438 * `doctype` (default `null`): optional DTD. Eg. `{'ext': 'hello.dtd'}`
439 * `headless` (default: `false`): omit the XML header. Added in 0.4.3.
440 * `allowSurrogateChars` (default: `false`): allows using characters from the Unicode
441 surrogate blocks.
442 * `cdata` (default: `false`): wrap text nodes in `<![CDATA[ ... ]]>` instead of
443 escaping when necessary. Does not add `<![CDATA[ ... ]]>` if it is not required.
444 Added in 0.4.5.
445
446`renderOpts`, `xmldec`,`doctype` and `headless` pass through to
447[xmlbuilder-js](https://github.com/oozcitak/xmlbuilder-js).
448
449Updating to new version
450=======================
451
452Version 0.2 changed the default parsing settings, but version 0.1.14 introduced
453the default settings for version 0.2, so these settings can be tried before the
454migration.
455
456```javascript
457var xml2js = require('xml2js');
458var parser = new xml2js.Parser(xml2js.defaults["0.2"]);
459```
460
461To get the 0.1 defaults in version 0.2 you can just use
462`xml2js.defaults["0.1"]` in the same place. This provides you with enough time
463to migrate to the saner way of parsing in `xml2js` 0.2. We try to make the
464migration as simple and gentle as possible, but some breakage cannot be
465avoided.
466
467So, what exactly did change and why? In 0.2 we changed some defaults to parse
468the XML in a more universal and sane way. So we disabled `normalize` and `trim`
469so `xml2js` does not cut out any text content. You can reenable this at will of
470course. A more important change is that we return the root tag in the resulting
471JavaScript structure via the `explicitRoot` setting, so you need to access the
472first element. This is useful for anybody who wants to know what the root node
473is and preserves more information. The last major change was to enable
474`explicitArray`, so everytime it is possible that one might embed more than one
475sub-tag into a tag, xml2js >= 0.2 returns an array even if the array just
476includes one element. This is useful when dealing with APIs that return
477variable amounts of subtags.
478
479Running tests, development
480==========================
481
482[![Build Status](https://travis-ci.org/Leonidas-from-XIV/node-xml2js.svg?branch=master)](https://travis-ci.org/Leonidas-from-XIV/node-xml2js)
483[![Coverage Status](https://coveralls.io/repos/Leonidas-from-XIV/node-xml2js/badge.svg?branch=)](https://coveralls.io/r/Leonidas-from-XIV/node-xml2js?branch=master)
484[![Dependency Status](https://david-dm.org/Leonidas-from-XIV/node-xml2js.svg)](https://david-dm.org/Leonidas-from-XIV/node-xml2js)
485
486The development requirements are handled by npm, you just need to install them.
487We also have a number of unit tests, they can be run using `npm test` directly
488from the project root. This runs zap to discover all the tests and execute
489them.
490
491If you like to contribute, keep in mind that `xml2js` is written in
492CoffeeScript, so don't develop on the JavaScript files that are checked into
493the repository for convenience reasons. Also, please write some unit test to
494check your behaviour and if it is some user-facing thing, add some
495documentation to this README, so people will know it exists. Thanks in advance!
496
497Getting support
498===============
499
500Please, if you have a problem with the library, first make sure you read this
501README. If you read this far, thanks, you're good. Then, please make sure your
502problem really is with `xml2js`. It is? Okay, then I'll look at it. Send me a
503mail and we can talk. Please don't open issues, as I don't think that is the
504proper forum for support problems. Some problems might as well really be bugs
505in `xml2js`, if so I'll let you know to open an issue instead :)
506
507But if you know you really found a bug, feel free to open an issue instead.