UNPKG

4.19 kBJavaScriptView Raw
1'use strict';
2var sax = require('sax'),
3 fs = require('fs'),
4 util = require('util'),
5 events = require('events')
6;
7function within(arr1, arr2) {
8 for (var i = 0; i < arr1.length; i++) {
9 if (arr1.indexOf(i) !== arr2.indexOf(i)) {
10 return false
11 }
12 }
13 return true
14}
15
16function string2path(s)
17{
18 if (typeof s === 'string') {
19 var k = {}
20 k.v = s.toLowerCase()
21 k.a = k.v.split('/')
22 if (k.a[0] === '') {
23 k.a.shift()
24 }
25 return k
26 }
27}
28
29
30function XMLSplitter(knife) {
31
32 if (!(this instanceof XMLSplitter)) {
33 return new XMLSplitter()
34 }
35
36 events.EventEmitter.call(this)
37
38
39 var self = this
40 var tagname = 'row'
41
42 // Propreties
43 self.result = {}
44 self.stack = []
45 self.path = []
46 self.cdata = ''
47 self.knifes = []
48 self.counter = 0
49 self.tracker = false
50 self.stream = require("sax").createStream(true, {trim:true})
51
52 // Polymoprphisme
53 if (Array.isArray(knife)) {
54 knife.forEach(function (item) {
55 self.knifes.push(string2path(item))
56 }
57 )
58 }
59 else {
60 self.knifes.push(string2path(knife))
61 }
62 if (self.knifes.length === 0) {
63 throw new Error('Invalid Parameter')
64 }
65
66
67
68 // Sax's handles
69 self.stream.onerror = function (e) {
70 // an error happened.
71 }
72 self.stream.onprocessinginstruction = function (pi) {
73 }
74 self.stream.ontext = function (v) {
75 if (self.tracker === false) {
76 return
77 }
78 self.cvalue('$t', v)
79 }
80 self.stream.oncomment = function (v) {
81 if (self.tracker === false) {
82 return
83 }
84 self.cvalue('$c', v)
85 }
86 self.stream.oncdata = function (v) {
87 if (self.tracker === false) {
88 return
89 }
90 self.cdata += v
91 }
92 self.stream.onopencdata = function () {
93 if (self.tracker === false) {
94 return
95 }
96 self.cdata = ''
97 }
98 self.stream.onclosecdata = function () {
99 if (self.tracker === false) {
100 return
101 }
102 self.cvalue('$cd', self.cdata)
103 self.cdata = ''
104 }
105 self.stream.onopentag = function (node) {
106 self.path.push(node.name.toLowerCase())
107
108
109 // Find a path
110 var t1 = self.knifes.reduce(function (prev, cur) { return (prev === true || self.path.length >= cur.a.length) }, false)
111 var t2 = self.knifes.reduce(function (prev, cur) { return (prev === true || within(cur, self.path)) }, false)
112
113 if (t1 === false || t2 === false) {
114 self.tracker = false
115 return
116 }
117
118 self.tracker = true
119
120 if (self.stack.length === 1 && node.name === tagname) {
121 self.result = self.cattr(node.attributes);
122 self.stack.push(this.result);
123 }
124 else {
125 self.stack.push(self.cvalue(node.name, self.cattr(node.attributes)))
126 }
127 }
128 self.stream.onclosetag = function (tag) {
129 var l = self.stack.pop()
130 var p = self.path.reduce(function (prev, cur) { return prev + '/' + cur }, '')
131
132 if (self.knifes.some(function checkPath(x) { return (x.v === p) })) {
133 self.emit('data', l, tag.replace(':', '$'), p)
134 self.counter++
135 self.stack = [{}]
136 }
137 self.path.pop()
138 if (self.path.length === 0) {
139 self.emit('end', self.counter)
140 }
141 }
142 self.stream.onready = function () {
143 var l = self.stack.pop()
144 }
145 self.stream.onend = function () {
146 }
147}
148util.inherits(XMLSplitter, events.EventEmitter)
149
150XMLSplitter.prototype.parseString = function (string, encoding) {
151 var self = this
152 self.stream.end(string, encoding || 'utf8')
153}
154
155XMLSplitter.prototype.parseStream = function (stream) {
156 var self = this;
157 stream.pipe(self.stream);
158}
159
160XMLSplitter.prototype.cvalue = function (n, v) {
161 var self = this
162 n = n.replace(':', '$')
163 var o = self.stack[self.stack.length - 1]
164 if (o == undefined) {
165 o = {}
166 o[n] = v
167 return o[n]
168 }
169 else if (o[n] == undefined) {
170 o[n] = v
171 return o[n]
172 }
173 else if (!Array.isArray(o[n])) {
174 var x = o[n]
175 o[n] = new Array(x, v)
176 return o[n][1]
177 }
178 else {
179 var i = o[n].push(v)
180 return o[n][i - 1]
181 }
182}
183
184XMLSplitter.prototype.cattr = function (o) {
185 var self = this
186 var r = {};
187 for (var key in o) {
188 if (o.hasOwnProperty(key) && o[key]) {
189 r[key.replace(':', '$')] = o[key];
190 }
191 }
192 return r;
193}
194
195module.exports = XMLSplitter