[Pkg-javascript-commits] [ltx] 206/469: configurable sax parsers (expat & saxjs backends)

Jonas Smedegaard dr at jones.dk
Wed Aug 31 13:03:04 UTC 2016


This is an automated email from the git hooks/post-receive script.

js pushed a commit to branch master
in repository ltx.

commit b6f9e1ba12a1bf53cea436fc22935447908cb7f8
Author: Astro <astro at spaceboyz.net>
Date:   Thu Mar 15 16:11:09 2012 +0100

    configurable sax parsers (expat & saxjs backends)
---
 lib/index.js       |  2 ++
 lib/parse.js       | 57 ++++++++++++++++++++++++++++++--------------------
 lib/sax_expat.js   | 39 ++++++++++++++++++++++++++++++++++
 lib/sax_saxjs.js   | 37 +++++++++++++++++++++++++++++++++
 test/parse-test.js | 61 ++++++++++++++++++++++++++++++++++--------------------
 5 files changed, 151 insertions(+), 45 deletions(-)

diff --git a/lib/index.js b/lib/index.js
index a9614b5..cb29b28 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -6,3 +6,5 @@ exports.escapeXml = element.escapeXml;
 
 exports.Parser = parse.Parser;
 exports.parse = parse.parse;
+exports.availableSaxParsers = parse.availableSaxParsers;
+exports.bestSaxParser = parse.bestSaxParser;
diff --git a/lib/parse.js b/lib/parse.js
index 0265c8f..60dcdd2 100644
--- a/lib/parse.js
+++ b/lib/parse.js
@@ -1,17 +1,31 @@
 var events = require('events');
-var util;
-try {
-    util = require('util');
-} catch(e) {
-    util = require('sys');
-}
-var expat = require('node-expat');
+var util = require('util');
+
+exports.availableSaxParsers = [];
+exports.bestSaxParser = null;
+['./sax_expat', './sax_saxjs'].forEach(function(modName) {
+    var mod;
+    try {
+	mod = require(modName);
+    } catch (e) {
+	console.error(e);
+    }
+    if (mod) {
+	exports.availableSaxParsers.push(mod);
+	if (!exports.bestSaxParser)
+	    exports.bestSaxParser = mod;
+    }
+});
 var element = require('./element');
 
-exports.Parser = function() {
+exports.Parser = function(saxParser) {
+    events.EventEmitter.call(this);
     var that = this;
 
-    this.parser = new expat.Parser('UTF-8');
+    var parserMod = saxParser || exports.bestSaxParser;
+    if (!parserMod)
+	throw new Error("No SAX parser available");
+    this.parser = new parserMod();
 
     var el;
     this.parser.addListener('startElement', function(name, attrs) {
@@ -38,24 +52,21 @@ exports.Parser = function() {
         if (el)
             el.t(str);
     });
+    this.parser.addListener('error', function(e) {
+	that.error = e;
+	that.emit('error', e);
+    });
 };
 util.inherits(exports.Parser, events.EventEmitter);
 
 exports.Parser.prototype.write = function(data) {
-    if (!this.parser.parse(data, false)) {
-        this.emit('error', new Error(this.parser.getError()));
-
-        // Premature error thrown,
-        // disable all functionality:
-        this.write = function() { };
-        this.end = function() { };
-    }
+    this.parser.write(data);
 };
 
-exports.Parser.prototype.end = function() {
-    if (!this.parser.parse('', true))
-        this.emit('error', new Error(this.parser.getError()));
-    else {
+exports.Parser.prototype.end = function(data) {
+    this.parser.end(data);
+
+    if (!this.error) {
 	if (this.tree)
 	    this.emit('tree', this.tree);
 	else
@@ -63,8 +74,8 @@ exports.Parser.prototype.end = function() {
     }
 };
 
-exports.parse = function(data) {
-    var p = new exports.Parser();
+exports.parse = function(data, saxParser) {
+    var p = new exports.Parser(saxParser);
     var result = null, error = null;
 
     p.on('tree', function(tree) {
diff --git a/lib/sax_expat.js b/lib/sax_expat.js
new file mode 100644
index 0000000..9d05cb2
--- /dev/null
+++ b/lib/sax_expat.js
@@ -0,0 +1,39 @@
+var util = require('util');
+var events = require('events');
+var expat = require('node-expat');
+
+var SaxExpat = module.exports = function SaxExpat() {
+    events.EventEmitter.call(this);
+    this.parser = new expat.Parser('UTF-8');
+
+    var that = this;
+    this.parser.on('startElement', function(name, attrs) {
+        that.emit('startElement', name, attrs);
+    });
+    this.parser.on('endElement', function(name) {
+        that.emit('endElement', name);
+    });
+    this.parser.on('text', function(str) {
+        that.emit('text', str);
+    });
+    // TODO: other events, esp. entityDecl (billion laughs!)
+};
+util.inherits(SaxExpat, events.EventEmitter);
+
+SaxExpat.prototype.write = function(data) {
+    if (!this.parser.parse(data, false)) {
+        this.emit('error', new Error(this.parser.getError()));
+
+        // Premature error thrown,
+        // disable all functionality:
+        this.write = function() { };
+        this.end = function() { };
+    }
+};
+
+SaxExpat.prototype.end = function(data) {
+    if (!this.parser.parse('', true))
+        this.emit('error', new Error(this.parser.getError()));
+    else
+        this.emit('end');
+};
diff --git a/lib/sax_saxjs.js b/lib/sax_saxjs.js
new file mode 100644
index 0000000..e24cc09
--- /dev/null
+++ b/lib/sax_saxjs.js
@@ -0,0 +1,37 @@
+var util = require('util');
+var events = require('events');
+var sax = require('sax');
+
+var SaxSaxjs = module.exports = function SaxSaxjs() {
+    events.EventEmitter.call(this);
+    this.parser = sax.parser(true);
+
+    var that = this;
+    this.parser.onopentag = function(a) {
+        that.emit('startElement', a.name, a.attributes);
+    };
+    this.parser.onclosetag = function(name) {
+        that.emit('endElement', name);
+    };
+    this.parser.ontext = function(str) {
+        that.emit('text', str);
+    };
+    this.parser.onend = function() {
+        that.emit('end');
+    };
+    this.parser.onerror = function(e) {
+        that.emit('error', e);
+    };
+    // TODO: other events, esp. entityDecl (billion laughs!)
+};
+util.inherits(SaxSaxjs, events.EventEmitter);
+
+SaxSaxjs.prototype.write = function(data) {
+    this.parser.write(data);
+};
+
+SaxSaxjs.prototype.end = function(data) {
+    if (data)
+        this.parser.write(data);
+    this.parser.close();
+};
diff --git a/test/parse-test.js b/test/parse-test.js
index 0f05708..7965ae0 100644
--- a/test/parse-test.js
+++ b/test/parse-test.js
@@ -2,26 +2,43 @@ var vows = require('vows'),
 assert = require('assert'),
 ltx = require('./../lib/index');
 
-vows.describe('ltx').addBatch({
-    'parsing': {
-        'simple document': function() {
-            var el = ltx.parse('<root/>');
-            assert.equal(el.name, 'root');
-            assert.equal(0, el.children.length);
-        },
-	'text with commas': function() {
-	    var el = ltx.parse("<body>sa'sa'1'sasa</body>");
-	    assert.equal("sa'sa'1'sasa", el.getText());
-	},
-        'erroneous document raises error': function() {
-            assert.throws(function() {
-                ltx.parse('<root></toor>');
-            });
-        },
-        'incomplete document raises error': function() {
-            assert.throws(function() {
-                ltx.parse('<root>');
-            });
+ltx.availableSaxParsers.forEach(function(saxParser) {
+    var parse = function(s) {
+        return ltx.parse(s, saxParser);
+    };
+    vows.describe('ltx with ' + saxParser.name).addBatch({
+        'parsing': {
+            'simple document': function() {
+                var el = parse('<root/>');
+                assert.equal(el.name, 'root');
+                assert.equal(0, el.children.length);
+            },
+            'text with commas': function() {
+                var el = parse("<body>sa'sa'1'sasa</body>");
+                assert.equal("sa'sa'1'sasa", el.getText());
+            },
+            'erroneous document raises error': function() {
+                assert.throws(function() {
+                    parse('<root></toor>');
+                });
+            },
+            'incomplete document raises error': function() {
+                assert.throws(function() {
+                    parse('<root>');
+                });
+            },
+            'namespace declaration': function() {
+                var el = parse("<root xmlns='https://github.com/astro/ltx'/>");
+                assert.equal(el.name, 'root');
+                assert.equal(el.attrs.xmlns, 'https://github.com/astro/ltx');
+                assert.ok(el.is('root', 'https://github.com/astro/ltx'));
+            },
+            'namespace declaration with prefix': function() {
+                var el = parse("<x:root xmlns:x='https://github.com/astro/ltx'/>");
+                assert.equal(el.name, 'x:root');
+                assert.equal(el.getName(), 'root');
+                assert.ok(el.is('root', 'https://github.com/astro/ltx'));
+            }
         }
-    }
-}).export(module);
+    }).export(module);
+});

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/ltx.git



More information about the Pkg-javascript-commits mailing list