xml-stream
Advanced tools
Comparing version 0.3.4 to 0.4.0
var events = require('events') | ||
, expat = require('node-expat') | ||
, FiniteAutomata = require('./finite-automata') | ||
, Iconv = require('iconv').Iconv | ||
; | ||
@@ -46,3 +47,3 @@ | ||
// Event listeners receive selected elements, context, and trace from root. | ||
function XmlStream(stream) { | ||
function XmlStream(stream, encoding) { | ||
events.EventEmitter.call(this); | ||
@@ -59,5 +60,21 @@ this._stream = stream; | ||
this._collect = false; | ||
// Set input stream encoding and create an iconv instance, | ||
// if conversion is required. Default working encoding is UTF-8, | ||
// so iconv is used when input is anything else, but UTF-8. | ||
this._encoding = encoding || null; | ||
this._encoder = makeEncoder(this._encoding); | ||
// Start parsing. | ||
parse.call(this); | ||
} | ||
// Either make an iconv instance, or not. | ||
function makeEncoder(encoding) { | ||
if (encoding && !/^utf-?8$/.test(encoding)) { | ||
return new Iconv(encoding, 'utf8'); | ||
} | ||
return null; | ||
} | ||
// Inherit events.EventEmitter. | ||
@@ -287,5 +304,5 @@ XmlStream.super_ = events.EventEmitter; | ||
// The Expat parser is assigned several listeners for this purpose. | ||
function parse(stream) { | ||
function parse() { | ||
var self = this; | ||
var xml = new expat.Parser(); | ||
var xml = new expat.Parser('utf-8'); | ||
var stack = []; | ||
@@ -450,7 +467,39 @@ var trace = {}; | ||
// Pass data from stream to parser. | ||
this._stream.on('data', function(data) { | ||
// This prelude array and string are used during encoding detection. | ||
// Incoming buffers are collected and parsing is postponed, | ||
// but only until the first tag. | ||
var prelude = ''; | ||
var preludeBuffers = []; | ||
// Parse incoming chunk. | ||
// Convert to UTF-8 or emit errors when appropriate. | ||
var parseChunk = function(data) { | ||
if (self._encoder) { | ||
data = self._encoder.convert(data); | ||
} | ||
if (!xml.parse(data, false)) { | ||
self.emit('error', xml.getError()); | ||
} | ||
} | ||
// Pass data from stream to parser. | ||
this._stream.on('data', function(data) { | ||
if (self._encoding) { | ||
parseChunk(data); | ||
} else { | ||
// We can't parse when the encoding is unknown, so we'll look into | ||
// the XML declaration, if there is one. For this, we need to buffer | ||
// incoming data until a full tag is received. | ||
preludeBuffers.push(data); | ||
prelude += data.toString(); | ||
if (/^\s*<[^>]+>/.test(prelude)) { | ||
var matches = prelude.match(/^\s*<\?xml[^>]+encoding="(.+)"[^>]*\?>/); | ||
self._encoding = matches ? matches[1] : 'utf8'; | ||
self._encoder = makeEncoder(self._encoding); | ||
for (var i = 0, n = preludeBuffers.length; i < n; i++) { | ||
parseChunk(preludeBuffers[i]); | ||
} | ||
} | ||
} | ||
}); | ||
@@ -457,0 +506,0 @@ |
@@ -9,3 +9,3 @@ { | ||
], | ||
"version": "0.3.4", | ||
"version": "0.4.0", | ||
"author": "AssistUnion <info@assistunion.com>", | ||
@@ -21,2 +21,3 @@ "maintainers": [ | ||
"dependencies": { | ||
"iconv": "~1.1.2", | ||
"node-expat": "~1.3.1" | ||
@@ -23,0 +24,0 @@ }, |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
25603
11
658
2
2
+ Addediconv@~1.1.2
+ Addediconv@1.1.3(transitive)