Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 390 lines (342 sloc) 12.434 kb
7dddb3c Marek Kubica More CoffeeScript sugar in require lines
authored
1 sax = require 'sax'
2 events = require 'events'
07e71f0 Marek Kubica Bi-directional support
authored
3 builder = require 'xmlbuilder'
6e83733 Marek Kubica Stripping BOM if at the beginning of file
authored
4 bom = require './bom'
83f1868 creynders Finalizes attribute and tag name processing
creynders authored
5 processors = require './processors'
054b79f Marek Kubica Added interface for passing in options
authored
6
5f54d69 Marek Kubica Implemented emptyTag option. If set, empty tags will not be {} but the v...
authored
7 # Underscore has a nice function for this, but we try to go without dependencies
8 isEmpty = (thing) ->
e77e346 Eric Schoffstall use double quotes, project standard (or so it looks like?)
contra authored
9 return typeof thing is "object" && thing? && Object.keys(thing).length is 0
5f54d69 Marek Kubica Implemented emptyTag option. If set, empty tags will not be {} but the v...
authored
10
a4b9205 creynders Facilitates tag and attribute name processing
creynders authored
11 processName = (processors, processedName) ->
12 processedName = process(processedName) for process in processors
13 return processedName
14
8de450c Add `cdata` option for unescaped text nodes when building
Jess Telford authored
15 requiresCDATA = (entry) ->
16 return entry.indexOf('&') >= 0 || entry.indexOf('>') >= 0 || entry.indexOf('<') >= 0
17
18 # Note that we do this manually instead of using xmlbuilder's `.dat` method
19 # since it does not support escaping the CDATA close entity (throws an error if
20 # it exists, and if it's pre-escaped).
21 wrapCDATA = (entry) ->
22 return "<![CDATA[#{escapeCDATA entry}]]>"
23
24 escapeCDATA = (entry) ->
25 # Split the CDATA section in two;
26 # The first contains the ']]'
27 # The second contains the '>'
28 # When later parsed, it will be put back together as ']]>'
29 return entry.replace ']]>', ']]]]><![CDATA[>'
30
65d414a creynders exposed processors in xml2js module
creynders authored
31 exports.processors = processors
32
16084e4 Marek Kubica Added a set of version dependent default options
authored
33 exports.defaults =
045141f Marek Kubica Restore indent for options object
authored
34 "0.1":
35 explicitCharkey: false
36 trim: true
37 # normalize implicates trimming, just so you know
38 normalize: true
39 # normalize tag names to lower case
40 normalizeTags: false
41 # set default attribute object key
42 attrkey: "@"
43 # set default char object key
44 charkey: "#"
45 # always put child nodes in an array
46 explicitArray: false
47 # ignore all attributes regardless
48 ignoreAttrs: false
49 # merge attributes and child elements onto parent object. this may
50 # cause collisions.
51 mergeAttrs: false
52 explicitRoot: false
53 validator: null
54 xmlns : false
55 # fold children elements into dedicated property (works only in 0.2)
56 explicitChildren: false
57 childkey: '@@'
58 charsAsChildren: false
9661766 Marek Kubica Made async execution optional
authored
59 # callbacks are async? not in 0.1 mode
60 async: false
51b3349 Marek Kubica Added strict option
authored
61 strict: true
83f1868 creynders Finalizes attribute and tag name processing
creynders authored
62 attrNameProcessors: null
63 tagNameProcessors: null
e15e32e Marek Kubica Set a more reasonable default value for emptyTag and corrected docs.
authored
64 emptyTag: ''
755e1d1 Mikhail Zyatin Adds explicit children mode that puts children element into distinct pro...
Sitin authored
65
045141f Marek Kubica Restore indent for options object
authored
66 "0.2":
67 explicitCharkey: false
68 trim: false
69 normalize: false
70 normalizeTags: false
71 attrkey: "$"
72 charkey: "_"
73 explicitArray: true
74 ignoreAttrs: false
75 mergeAttrs: false
76 explicitRoot: true
77 validator: null
78 xmlns : false
79 explicitChildren: false
80 childkey: '$$'
81 charsAsChildren: false
9661766 Marek Kubica Made async execution optional
authored
82 # not async in 0.2 mode either
83 async: false
51b3349 Marek Kubica Added strict option
authored
84 strict: true
83f1868 creynders Finalizes attribute and tag name processing
creynders authored
85 attrNameProcessors: null
86 tagNameProcessors: null
07e71f0 Marek Kubica Bi-directional support
authored
87 # xml building options
88 rootName: 'root'
89 xmldec: {'version': '1.0', 'encoding': 'UTF-8', 'standalone': true}
90 doctype: null
91 renderOpts: { 'pretty': true, 'indent': ' ', 'newline': '\n' }
e94799c Leore Avidar Add headless option
leore authored
92 headless: false
442a814 Marek Kubica Parse in chunks when options.async is set
authored
93 chunkSize: 10000
e15e32e Marek Kubica Set a more reasonable default value for emptyTag and corrected docs.
authored
94 emptyTag: ''
8de450c Add `cdata` option for unescaped text nodes when building
Jess Telford authored
95 cdata: false
262df33 Marek Kubica Merge branch 'master' of github.com:Leonidas-from-XIV/node-xml2js
authored
96
a644bfd salsita-buildserver Created special exception for validation errors and added tests
salsita-buildserver authored
97 class exports.ValidationError extends Error
98 constructor: (message) ->
99 @message = message
16084e4 Marek Kubica Added a set of version dependent default options
authored
100
07e71f0 Marek Kubica Bi-directional support
authored
101 class exports.Builder
102 constructor: (opts) ->
103 # copy this versions default options
104 @options = {}
105 @options[key] = value for own key, value of exports.defaults["0.2"]
106 # overwrite them with the specified options, if any
107 @options[key] = value for own key, value of opts
108
109 buildObject: (rootObj) ->
110 attrkey = @options.attrkey
111 charkey = @options.charkey
112
113 # If there is a sane-looking first element to use as the root,
114 # and the user hasn't specified a non-default rootName,
115 if ( Object.keys(rootObj).length is 1 ) and ( @options.rootName == exports.defaults['0.2'].rootName )
116 # we'll take the first element as the root element
117 rootName = Object.keys(rootObj)[0]
118 rootObj = rootObj[rootName]
119 else
120 # otherwise we'll use whatever they've set, or the default
121 rootName = @options.rootName
122
8de450c Add `cdata` option for unescaped text nodes when building
Jess Telford authored
123 render = (element, obj) =>
07e71f0 Marek Kubica Bi-directional support
authored
124 if typeof obj isnt 'object'
125 # single element, just append it as text
8de450c Add `cdata` option for unescaped text nodes when building
Jess Telford authored
126 if @options.cdata && requiresCDATA obj
127 element.raw wrapCDATA obj
128 else
129 element.txt obj
07e71f0 Marek Kubica Bi-directional support
authored
130 else
131 for own key, child of obj
132 # Case #1 Attribute
133 if key is attrkey
134 if typeof child is "object"
135 # Inserts tag attributes
136 for attr, value of child
137 element = element.att(attr, value)
138
139 # Case #2 Char data (CDATA, etc.)
140 else if key is charkey
8de450c Add `cdata` option for unescaped text nodes when building
Jess Telford authored
141 if @options.cdata && requiresCDATA child
142 element = element.raw wrapCDATA child
143 else
144 element = element.txt child
07e71f0 Marek Kubica Bi-directional support
authored
145
146 # Case #3 Array data
208dff5 Marek Kubica Use dedicated method to check for arrayness
authored
147 else if Array.isArray child
07e71f0 Marek Kubica Bi-directional support
authored
148 for own index, entry of child
149 if typeof entry is 'string'
8de450c Add `cdata` option for unescaped text nodes when building
Jess Telford authored
150 if @options.cdata && requiresCDATA entry
151 element = element.ele(key).raw(wrapCDATA entry).up()
152 else
153 element = element.ele(key, entry).up()
07e71f0 Marek Kubica Bi-directional support
authored
154 else
155 element = arguments.callee(element.ele(key), entry).up()
156
157 # Case #4 Objects
158 else if typeof child is "object"
159 element = arguments.callee(element.ele(key), child).up()
160
161 # Case #5 String and remaining types
162 else
163 element = element.ele(key, child.toString()).up()
164
165 element
166
e7fe683 Marek Kubica Make patch work on my system
authored
167 rootElement = builder.create(rootName, @options.xmldec, @options.doctype,
168 headless: @options.headless)
07e71f0 Marek Kubica Bi-directional support
authored
169
170 render(rootElement, rootObj).end(@options.renderOpts)
171
a130536 Marek Kubica Ported to the CoffeeScript class system
authored
172 class exports.Parser extends events.EventEmitter
054b79f Marek Kubica Added interface for passing in options
authored
173 constructor: (opts) ->
05c7f43 Marek Kubica Added unit test and fix in the constructor making the test pass
authored
174 # if this was called without 'new', create an instance with new and return
175 return new exports.Parser opts unless @ instanceof exports.Parser
16084e4 Marek Kubica Added a set of version dependent default options
authored
176 # copy this versions default options
2164d82 Marek Kubica Fixed shallow copy of default options
authored
177 @options = {}
df32c23 Marek Kubica Switched to 0.2 defaults, adjusting unittests
authored
178 @options[key] = value for own key, value of exports.defaults["0.2"]
054b79f Marek Kubica Added interface for passing in options
authored
179 # overwrite them with the specified options, if any
c37c82a Marek Kubica Made parser resettable
authored
180 @options[key] = value for own key, value of opts
b49f965 Mike Schilling Add xmlns flag, to enable adding namespace information to elements
mikeatemotive authored
181 # define the key used for namespaces
182 if @options.xmlns
183 @options.xmlnskey = @options.attrkey + "ns"
a4b9205 creynders Facilitates tag and attribute name processing
creynders authored
184 if @options.normalizeTags
83f1868 creynders Finalizes attribute and tag name processing
creynders authored
185 if ! @options.tagNameProcessors
186 @options.tagNameProcessors = []
187 @options.tagNameProcessors.unshift processors.normalize
882b71d Marek Kubica Pedantic blank adjustment
authored
188
c37c82a Marek Kubica Made parser resettable
authored
189 @reset()
054b79f Marek Kubica Added interface for passing in options
authored
190
442a814 Marek Kubica Parse in chunks when options.async is set
authored
191 processAsync: =>
d742891 Marek Kubica Consume the string that was passed
authored
192 if @remaining.length <= @options.chunkSize
193 chunk = @remaining
194 @remaining = ''
195 @saxParser = @saxParser.write chunk
442a814 Marek Kubica Parse in chunks when options.async is set
authored
196 @saxParser.close()
d742891 Marek Kubica Consume the string that was passed
authored
197 else
198 chunk = @remaining.substr 0, @options.chunkSize
199 @remaining = @remaining.substr @options.chunkSize, @remaining.length
200 @saxParser = @saxParser.write chunk
201 setImmediate @processAsync
442a814 Marek Kubica Parse in chunks when options.async is set
authored
202
f169330 Matthias Hölzl Improve consistency when explicitArray + mergeAttrs are both true
hoelzl authored
203 assignOrPush: (obj, key, newValue) =>
204 if key not of obj
205 if not @options.explicitArray
206 obj[key] = newValue
207 else
208 obj[key] = [newValue]
209 else
210 obj[key] = [obj[key]] if not (obj[key] instanceof Array)
211 obj[key].push newValue
212
c37c82a Marek Kubica Made parser resettable
authored
213 reset: =>
b863ed9 Marek Kubica Fixed duplicate listeners problem by deleting them on reset
authored
214 # remove all previous listeners for events, to prevent event listener
215 # accumulation
216 @removeAllListeners()
e1687bc Marek Kubica Made test pass after thinking about the expected result
authored
217 # make the SAX parser. tried trim and normalize, but they are not
218 # very helpful
51b3349 Marek Kubica Added strict option
authored
219 @saxParser = sax.parser @options.strict, {
e1687bc Marek Kubica Made test pass after thinking about the expected result
authored
220 trim: false,
b49f965 Mike Schilling Add xmlns flag, to enable adding namespace information to elements
mikeatemotive authored
221 normalize: false,
222 xmlns: @options.xmlns
e1687bc Marek Kubica Made test pass after thinking about the expected result
authored
223 }
de509d3 Marek Kubica Remove whitespace lines
authored
224
a48e4a4 Ștefan Rusu Emits an error even for the sax event onerror.
SaltwaterC authored
225 # emit one error event if the sax parser fails. this is mostly a hack, but
226 # the sax parser isn't state of the art either.
eaae5a0 Todd Bryan Catch thrown sax errors; only invoke parseString callback once
toddrbryan authored
227 @saxParser.errThrown = false
a48e4a4 Ștefan Rusu Emits an error even for the sax event onerror.
SaltwaterC authored
228 @saxParser.onerror = (error) =>
eaae5a0 Todd Bryan Catch thrown sax errors; only invoke parseString callback once
toddrbryan authored
229 @saxParser.resume()
230 if ! @saxParser.errThrown
231 @saxParser.errThrown = true
a48e4a4 Ștefan Rusu Emits an error even for the sax event onerror.
SaltwaterC authored
232 @emit "error", error
de509d3 Marek Kubica Remove whitespace lines
authored
233
a215dc4 Marek Kubica Added comments and false not so 'ended' is never undefined
authored
234 # another hack to avoid throwing exceptions when the parsing has ended
235 # but the user-supplied callback throws an error
236 @saxParser.ended = false
eaae5a0 Todd Bryan Catch thrown sax errors; only invoke parseString callback once
toddrbryan authored
237
a130536 Marek Kubica Ported to the CoffeeScript class system
authored
238 # always use the '#' key, even if there are no subkeys
29a619b Marek Kubica Made explicitCharkey test nicer
authored
239 # setting this property by and is deprecated, yet still supported.
240 # better pass it as explicitCharkey option to the constructor
c37c82a Marek Kubica Made parser resettable
authored
241 @EXPLICIT_CHARKEY = @options.explicitCharkey
a130536 Marek Kubica Ported to the CoffeeScript class system
authored
242 @resultObject = null
243 stack = []
94da699 Marek Kubica Do not introduce more attributes, EXPLICIT_CHARKEY is only backward-comp...
authored
244 # aliases, so we don't have to type so much
c37c82a Marek Kubica Made parser resettable
authored
245 attrkey = @options.attrkey
246 charkey = @options.charkey
882b71d Marek Kubica Pedantic blank adjustment
authored
247
a130536 Marek Kubica Ported to the CoffeeScript class system
authored
248 @saxParser.onopentag = (node) =>
249 obj = {}
94da699 Marek Kubica Do not introduce more attributes, EXPLICIT_CHARKEY is only backward-comp...
authored
250 obj[charkey] = ""
c37c82a Marek Kubica Made parser resettable
authored
251 unless @options.ignoreAttrs
d41d510 Michael Hart Added option to ignore all attributes entirely
mhart authored
252 for own key of node.attributes
c8a2605 Raoul Millais Add support for merging attributes with child elements
raoulmillais authored
253 if attrkey not of obj and not @options.mergeAttrs
d41d510 Michael Hart Added option to ignore all attributes entirely
mhart authored
254 obj[attrkey] = {}
f169330 Matthias Hölzl Improve consistency when explicitArray + mergeAttrs are both true
hoelzl authored
255 newValue = node.attributes[key]
83f1868 creynders Finalizes attribute and tag name processing
creynders authored
256 processedKey = if @options.attrNameProcessors then processName(@options.attrNameProcessors, key) else key
c8a2605 Raoul Millais Add support for merging attributes with child elements
raoulmillais authored
257 if @options.mergeAttrs
a4b9205 creynders Facilitates tag and attribute name processing
creynders authored
258 @assignOrPush obj, processedKey, newValue
c8a2605 Raoul Millais Add support for merging attributes with child elements
raoulmillais authored
259 else
a4b9205 creynders Facilitates tag and attribute name processing
creynders authored
260 obj[attrkey][processedKey] = newValue
a130536 Marek Kubica Ported to the CoffeeScript class system
authored
261
262 # need a place to store the node name
83f1868 creynders Finalizes attribute and tag name processing
creynders authored
263 obj["#name"] = if @options.tagNameProcessors then processName(@options.tagNameProcessors, node.name) else node.name
b49f965 Mike Schilling Add xmlns flag, to enable adding namespace information to elements
mikeatemotive authored
264 if (@options.xmlns)
882b71d Marek Kubica Pedantic blank adjustment
authored
265 obj[@options.xmlnskey] = {uri: node.uri, local: node.local}
a130536 Marek Kubica Ported to the CoffeeScript class system
authored
266 stack.push obj
de509d3 Marek Kubica Remove whitespace lines
authored
267
a130536 Marek Kubica Ported to the CoffeeScript class system
authored
268 @saxParser.onclosetag = =>
269 obj = stack.pop()
270 nodeName = obj["#name"]
271 delete obj["#name"]
4f74597 Jackson Tian Pass exception correctly
JacksonTian authored
272
a1812c3 Frank Xu fix error when parsing CDATA with only whitespace(s), #77
yyfrankyy authored
273 cdata = obj.cdata
274 delete obj.cdata
275
a130536 Marek Kubica Ported to the CoffeeScript class system
authored
276 s = stack[stack.length - 1]
277 # remove the '#' key altogether if it's blank
a1812c3 Frank Xu fix error when parsing CDATA with only whitespace(s), #77
yyfrankyy authored
278 if obj[charkey].match(/^\s*$/) and not cdata
26c8677 Jackson Tian Fix the empty node
JacksonTian authored
279 emptyStr = obj[charkey]
94da699 Marek Kubica Do not introduce more attributes, EXPLICIT_CHARKEY is only backward-comp...
authored
280 delete obj[charkey]
a33d8f2 Marek Kubica Added initial, not yet working automated translation by js2coffee
authored
281 else
c37c82a Marek Kubica Made parser resettable
authored
282 obj[charkey] = obj[charkey].trim() if @options.trim
283 obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim() if @options.normalize
a130536 Marek Kubica Ported to the CoffeeScript class system
authored
284 # also do away with '#' key altogether, if there's no subkeys
285 # unless EXPLICIT_CHARKEY is set
94da699 Marek Kubica Do not introduce more attributes, EXPLICIT_CHARKEY is only backward-comp...
authored
286 if Object.keys(obj).length == 1 and charkey of obj and not @EXPLICIT_CHARKEY
287 obj = obj[charkey]
a33d8f2 Marek Kubica Added initial, not yet working automated translation by js2coffee
authored
288
26c8677 Jackson Tian Fix the empty node
JacksonTian authored
289 if (isEmpty obj)
e15e32e Marek Kubica Set a more reasonable default value for emptyTag and corrected docs.
authored
290 obj = if @options.emptyTag != '' then @options.emptyTag else emptyStr
5f54d69 Marek Kubica Implemented emptyTag option. If set, empty tags will not be {} but the v...
authored
291
5cb2296 salsita-buildserver Added support for an optional validator for schema-driven generation
salsita-buildserver authored
292 if @options.validator?
b023b38 salsita-buildserver Improved validator interface to decouple better from our internal detail...
salsita-buildserver authored
293 xpath = "/" + (node["#name"] for node in stack).concat(nodeName).join("/")
4f74597 Jackson Tian Pass exception correctly
JacksonTian authored
294 try
295 obj = @options.validator(xpath, s and s[nodeName], obj)
296 catch err
297 @emit "error", err
5cb2296 salsita-buildserver Added support for an optional validator for schema-driven generation
salsita-buildserver authored
298
755e1d1 Mikhail Zyatin Adds explicit children mode that puts children element into distinct pro...
Sitin authored
299 # put children into <childkey> property and unfold chars if necessary
300 if @options.explicitChildren and not @options.mergeAttrs and typeof obj is 'object'
301 node = {}
302 # separate attributes
303 if @options.attrkey of obj
304 node[@options.attrkey] = obj[@options.attrkey]
305 delete obj[@options.attrkey]
306 # separate char data
307 if not @options.charsAsChildren and @options.charkey of obj
308 node[@options.charkey] = obj[@options.charkey]
309 delete obj[@options.charkey]
310
a3cb66e Mikhail Zyatin Skips empty children properties in `explicitChildren` mode.
Sitin authored
311 if Object.getOwnPropertyNames(obj).length > 0
312 node[@options.childkey] = obj
313
755e1d1 Mikhail Zyatin Adds explicit children mode that puts children element into distinct pro...
Sitin authored
314 obj = node
315
5f54d69 Marek Kubica Implemented emptyTag option. If set, empty tags will not be {} but the v...
authored
316 # check whether we closed all the open tags
a130536 Marek Kubica Ported to the CoffeeScript class system
authored
317 if stack.length > 0
f169330 Matthias Hölzl Improve consistency when explicitArray + mergeAttrs are both true
hoelzl authored
318 @assignOrPush s, nodeName, obj
a130536 Marek Kubica Ported to the CoffeeScript class system
authored
319 else
e024b03 Marek Kubica Added explicitRoot option, for folks who also want to have the root tag ...
authored
320 # if explicitRoot was specified, wrap stuff in the root tag name
c37c82a Marek Kubica Made parser resettable
authored
321 if @options.explicitRoot
e024b03 Marek Kubica Added explicitRoot option, for folks who also want to have the root tag ...
authored
322 # avoid circular references
323 old = obj
324 obj = {}
325 obj[nodeName] = old
326
a130536 Marek Kubica Ported to the CoffeeScript class system
authored
327 @resultObject = obj
a215dc4 Marek Kubica Added comments and false not so 'ended' is never undefined
authored
328 # parsing has ended, mark that so we won't throw exceptions from
329 # here anymore
f264639 Dave Aitken Don't emit 'error' for excptns caught in 'end' cbs
actionshrimp authored
330 @saxParser.ended = true
a130536 Marek Kubica Ported to the CoffeeScript class system
authored
331 @emit "end", @resultObject
8d18e8b Marek Kubica Made one test case pass, still working on the others
authored
332
a1812c3 Frank Xu fix error when parsing CDATA with only whitespace(s), #77
yyfrankyy authored
333 ontext = (text) =>
a130536 Marek Kubica Ported to the CoffeeScript class system
authored
334 s = stack[stack.length - 1]
335 if s
94da699 Marek Kubica Do not introduce more attributes, EXPLICIT_CHARKEY is only backward-comp...
authored
336 s[charkey] += text
a1812c3 Frank Xu fix error when parsing CDATA with only whitespace(s), #77
yyfrankyy authored
337 s
338
339 @saxParser.ontext = ontext
340 @saxParser.oncdata = (text) =>
341 s = ontext text
342 if s
343 s.cdata = true
a33d8f2 Marek Kubica Added initial, not yet working automated translation by js2coffee
authored
344
f7436ce Eric Schoffstall add support for callbacks in parseString
contra authored
345 parseString: (str, cb) =>
e77e346 Eric Schoffstall use double quotes, project standard (or so it looks like?)
contra authored
346 if cb? and typeof cb is "function"
347 @on "end", (result) ->
c37c82a Marek Kubica Made parser resettable
authored
348 @reset()
442a814 Marek Kubica Parse in chunks when options.async is set
authored
349 cb null, result
e77e346 Eric Schoffstall use double quotes, project standard (or so it looks like?)
contra authored
350 @on "error", (err) ->
c37c82a Marek Kubica Made parser resettable
authored
351 @reset()
442a814 Marek Kubica Parse in chunks when options.async is set
authored
352 cb err
c71e66c Marek Kubica Removed dangling whitespace
authored
353
442a814 Marek Kubica Parse in chunks when options.async is set
authored
354 str = str.toString()
355 if str.trim() is ''
2253fdc Marcelo Diniz Emits 'end' event if trimmed string argument is ''
mdiniz authored
356 @emit "end", null
357 return true
c71e66c Marek Kubica Removed dangling whitespace
authored
358
eaae5a0 Todd Bryan Catch thrown sax errors; only invoke parseString callback once
toddrbryan authored
359 try
442a814 Marek Kubica Parse in chunks when options.async is set
authored
360 str = bom.stripBOM str
361 if @options.async
d742891 Marek Kubica Consume the string that was passed
authored
362 @remaining = str
442a814 Marek Kubica Parse in chunks when options.async is set
authored
363 setImmediate @processAsync
364 @saxParser
365 @saxParser.write(str).close()
eaae5a0 Todd Bryan Catch thrown sax errors; only invoke parseString callback once
toddrbryan authored
366 catch err
f264639 Dave Aitken Don't emit 'error' for excptns caught in 'end' cbs
actionshrimp authored
367 unless @saxParser.errThrown or @saxParser.ended
eaae5a0 Todd Bryan Catch thrown sax errors; only invoke parseString callback once
toddrbryan authored
368 @emit 'error', err
369 @saxParser.errThrown = true
3fc65f6 CandleCandle propagate errors that are not parse errors. fixes #172
CandleCandle authored
370 else if @saxParser.ended
371 throw err
5cb2296 salsita-buildserver Added support for an optional validator for schema-driven generation
salsita-buildserver authored
372
2e9024a Marek Kubica Implemented code to fulfil test cases
authored
373 exports.parseString = (str, a, b) ->
374 # let's determine what we got as arguments
375 if b?
376 if typeof b == 'function'
377 cb = b
378 if typeof a == 'object'
379 options = a
380 else
381 # well, b is not set, so a has to be a callback
382 if typeof a == 'function'
383 cb = a
384 # and options should be empty - default
385 options = {}
386
387 # the rest is super-easy
388 parser = new exports.Parser options
389 parser.parseString str, cb
Something went wrong with that request. Please try again.