156
README.md
156
README.md
@@ -1 +1,155 @@
|
||||
# xml-streamer
|
||||
# xml-streamer
|
||||
|
||||
[](https://travis-ci.org/Sai1919/xml-streamer)
|
||||
## Motivation
|
||||
|
||||
You use [Node.js](https://nodejs.org) for speed? You process XML streams? Then you want the fastest XML to JS parser: xml-streamer
|
||||
|
||||
## Install
|
||||
|
||||
```
|
||||
npm install xml-streamer
|
||||
```
|
||||
|
||||
## Basic Usage
|
||||
|
||||
```javascript
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
var Parser = require('xml-streamer')
|
||||
var opts = {resourcePath: '/items/item'}
|
||||
|
||||
var parser = new Parser(opts)
|
||||
|
||||
parser.on('data', function (data) {
|
||||
// consume the data object here
|
||||
})
|
||||
|
||||
parser.on('end', function () {
|
||||
// parsing ended no more data events will be raised
|
||||
})
|
||||
|
||||
parser.on('error', function (error) {
|
||||
// error occurred
|
||||
// NOTE: when error emit emitted no end event will be emitted
|
||||
console.error(error)
|
||||
})
|
||||
|
||||
xmlStream.pipe(parser) // pipe your input xmlStream to parser.
|
||||
// readable
|
||||
parser.on('readable', function () {
|
||||
// if you don't want to consume "data" on "data" events you can wait for readable event and consume data by calling parser.read()
|
||||
})
|
||||
}())
|
||||
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
* `#on('readable' function () {})`
|
||||
* `#on('end' function () {})` `Note: No end event will be emmited when error is emitted`
|
||||
* `#on('error' function (err) {})`
|
||||
* `#on('nodeName' function (err) {})` //if you are interested to listen on the "nodeName" instead of "data"
|
||||
* `#stop()` pauses
|
||||
* `#resume()` resumes
|
||||
* `#read()` returns object if stream is readable
|
||||
|
||||
## Available Constructor Options
|
||||
|
||||
* `resourcePath`: `Type: String` Manditory field. Used to extract the XML nodes that you are interested in.
|
||||
|
||||
// Ex: let the XML be
|
||||
```xml
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<items>
|
||||
<item id="1" test= 'hello'>
|
||||
<subitem sub= "TESTING SUB">one</subitem>
|
||||
<subitem sub= "2">two</subitem>
|
||||
</item>
|
||||
<item id="2">
|
||||
<subitem>three</subitem>
|
||||
<subitem>four</subitem>
|
||||
<subitem>five</subitem>
|
||||
</item>
|
||||
</items>
|
||||
```
|
||||
if you are interested in `item` nodes then resourcePath would be: `/items/item`
|
||||
if you are interested in `subitem` nodes then resourcePath would be: `/items/item/subitem`
|
||||
if you are interested in `items` nodes then resourcePath would be: `/items`
|
||||
|
||||
* `emitOnNodeName`: `Type: Boolean` Optional field. Set this to true if you want to listen on node names instead of data event. `default: false`
|
||||
|
||||
// Ex: consider the above XML snippet
|
||||
```javascript
|
||||
if you are interested in `item` nodes. You can listen for `data` event by default to get those nodes in JS object form
|
||||
|
||||
parser.on('data', function (data) {
|
||||
// item nodes as javascipt objects
|
||||
})
|
||||
|
||||
or else you can set `emitOnNodeName: true` and listen on node names like
|
||||
|
||||
parser.on('item', function (data) {
|
||||
// item nodes as javascipt objects
|
||||
})
|
||||
```
|
||||
|
||||
`NOTE:` when you set `emitOnNodeName:true` "data" events are emitted normally. So make sure you don't listen for both the events.
|
||||
|
||||
* `attrsKey`: `Type: String` Optional field. pass the value with which you want to reference attributes of a node in its object form. `default: '$'`
|
||||
|
||||
* `textKey`: `Type: String` Optional field. pass the value with which you want to reference node value in its object form. `default: '_'`
|
||||
|
||||
// In the above XML snippet `subitem` node will look like this after converted to javascript object
|
||||
```javascript
|
||||
{
|
||||
"$": {
|
||||
"sub": "TESTING SUB"
|
||||
}
|
||||
"_": "one"
|
||||
}
|
||||
// if you want like this
|
||||
{
|
||||
"attrs": {
|
||||
"sub": "TESTING SUB"
|
||||
},
|
||||
"text": "one"
|
||||
}
|
||||
```
|
||||
// Then set `attrsKey= "attrs"` and `textKey= "text"`
|
||||
|
||||
|
||||
## upcoming features
|
||||
|
||||
1. `allowing to listen on interested nodes instead of passing resourcePath in options`
|
||||
2. `handling of compressed streams`
|
||||
3. `handling of different encodings`
|
||||
|
||||
|
||||
## Namespace handling
|
||||
|
||||
A word about special parsing of *xmlns:* Note that "resourcePath" in the options is not an XPATH.
|
||||
So the value given to the resourcePath is treated as simple value and no expression evaluations are done.
|
||||
|
||||
## Benchmark
|
||||
|
||||
`xml-streamer` internally uses `node-expat`
|
||||
|
||||
`npm run benchmark`
|
||||
|
||||
| module | ops/sec | native | XML compliant | stream |
|
||||
|---------------------------------------------------------------------------------------|--------:|:------:|:-------------:|:--------------:|
|
||||
| [sax-js](https://github.com/isaacs/sax-js) | 99,412 | ☐ | ☑ | ☑ |
|
||||
| [node-xml](https://github.com/dylang/node-xml) | 130,631 | ☐ | ☑ | ☑ |
|
||||
| [libxmljs](https://github.com/polotek/libxmljs) | 276,136 | ☑ | ☑ | ☐ |
|
||||
| **node-expat** | 322,769 | ☑ | ☑ | ☑ |
|
||||
|
||||
Higher is better.
|
||||
|
||||
## Testing
|
||||
|
||||
```
|
||||
npm install -g standard
|
||||
npm test
|
||||
```
|
||||
@@ -27,12 +27,13 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha": "3.1.2",
|
||||
"should": "11.1.1"
|
||||
"should": "11.1.1",
|
||||
"standard": "8.5.0"
|
||||
},
|
||||
"optionalDependencies": {},
|
||||
"main": "./parser",
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
"test": "mocha && standard"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
|
||||
@@ -25,6 +25,7 @@ describe('Tests', function () {
|
||||
})
|
||||
|
||||
parser.on('error', function (err) {
|
||||
should(err).not.be.ok()
|
||||
done(err)
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user