UNPKG

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