Skip to content
Newer
Older
100644 71 lines (47 sloc) 1.77 KB
1105b21 @seanhess simple object events
seanhess authored Sep 18, 2012
1 expat = require 'node-expat'
2 events = require 'events'
3
045cbd6 @seanhess stripping namespaces
seanhess authored Sep 21, 2012
4 exports.parse = (readStream, options = {}) ->
5 options.stripNamespaces ?= true
1105b21 @seanhess simple object events
seanhess authored Sep 18, 2012
6
7 parser = new expat.Parser("UTF-8")
8 emitter = new events.EventEmitter()
9
045cbd6 @seanhess stripping namespaces
seanhess authored Sep 21, 2012
10 readStream.on 'data', (data) -> parser.parse data.toString()
11 readStream.on 'end', -> process.nextTick -> emitter.emit 'end'
12 readStream.on 'error', (err) -> emitter.emit 'error', err
13 readStream.on 'close', -> emitter.emit 'close'
1105b21 @seanhess simple object events
seanhess authored Sep 18, 2012
14
15
16
17
18 # parse EVERYTHING inside of them.
19 each = (nodeName, eachNode) ->
20
21 eachNodeDelayed = (node) ->
22 process.nextTick ->
23 eachNode node
24
25 currentNode = null
26
27 parser.on 'error', (err) ->
28 emitter.emit 'error', err
29
30 parser.on 'startElement', (name, attrs) ->
045cbd6 @seanhess stripping namespaces
seanhess authored Sep 21, 2012
31 if options.stripNamespaces then name = stripNamespace name
451ef49 @seanhess fixed memory problems
seanhess authored Sep 20, 2012
32 if name is nodeName or currentNode
33 currentNode = {$name: name, $:attrs, $parent: currentNode}
1105b21 @seanhess simple object events
seanhess authored Sep 18, 2012
34
35 parser.on 'text', (text) ->
36 return if not currentNode?
37 currentNode.$text ?= ""
38 currentNode.$text += text
39
40
451ef49 @seanhess fixed memory problems
seanhess authored Sep 20, 2012
41 # ok, we only want to collect things if we are under a current node
42
1105b21 @seanhess simple object events
seanhess authored Sep 18, 2012
43 parser.on 'endElement', (name) ->
44 return if not currentNode?
45
451ef49 @seanhess fixed memory problems
seanhess authored Sep 20, 2012
46 if currentNode.$name is nodeName
1105b21 @seanhess simple object events
seanhess authored Sep 18, 2012
47
451ef49 @seanhess fixed memory problems
seanhess authored Sep 20, 2012
48 if currentNode.$parent
49 throw new Error "Top-level node should not have a parent. Possible memory leak"
50
51 eachNodeDelayed currentNode
52
53 parent = currentNode.$parent
1105b21 @seanhess simple object events
seanhess authored Sep 18, 2012
54 if parent?
55 delete currentNode.$parent
56 parent.$children ?= []
57 parent.$children.push currentNode
58 parent[currentNode.$name] = currentNode
59
60 currentNode = parent
61
62
63 return {
64 each: each
65 on: (e, cb) -> emitter.on e, cb
66 pause: -> readStream.pause()
67 resume: -> readStream.resume()
68 }
69
045cbd6 @seanhess stripping namespaces
seanhess authored Sep 21, 2012
70 stripNamespace = (name) -> name.replace /^.*:/, ""
Something went wrong with that request. Please try again.