Permalink
Browse files

OS-721 add node-expat to parse XML

  • Loading branch information...
joshwilsdon committed Nov 15, 2011
1 parent f0b3529 commit b1a52e5335854135e69e8bf4fc474ce53b5803a4
View
@@ -1,6 +1,8 @@
CC=gcc
CFLAGS=-Wall
-TARGETS=bootparams disklist removable_disk disk_size node-kstat/build/default/kstat.node zoneevent
+TARGETS=bootparams disklist removable_disk disk_size \
+ node-kstat/build/default/kstat.node zoneevent \
+ node-expat/build/default/node-expat.node
SMARTDC_TARGETS=has_hvx
DESTDIR=../proto
NODE_WAF=$(PWD)/../proto/usr/bin/node-waf
@@ -23,9 +25,14 @@ install: $(TARGETS) sysinfo
mkdir -m 0755 -p $(DESTDIR)/usr/node_modules
find node_modules -type f -exec cp {} $(DESTDIR)/usr/node_modules/ \;
cp node-kstat/build/default/kstat.node $(DESTDIR)/usr/node_modules/
- mkdir -m 0755 -p $(DESTDIR)/usr/vm/
rm -rf $(DESTDIR)/usr/vm
cp -PR vm $(DESTDIR)/usr/
+ mkdir -m 0755 -p $(DESTDIR)/usr/vm/node_modules
+ cp node-expat/build/default/node-expat.node \
+ $(DESTDIR)/usr/vm/node_modules/expat_binding.node
+ cat node-expat/lib/node-expat.js | \
+ sed -e "s|var expat.*;|var expat = require('expat_binding');|" > \
+ $(DESTDIR)/usr/vm/node_modules/node-expat.js
cp zoneevent $(DESTDIR)/usr/vm/sbin/zoneevent
mkdir -p $(DESTDIR)/lib/svc/manifest/system
cp vm/smf/system-vmadmd.xml $(DESTDIR)/lib/svc/manifest/system/system-vmadmd.xml
@@ -51,6 +58,9 @@ has_hvx: has_hvx.c
node-kstat/build/default/kstat.node: node-kstat/kstat.cc $(NODE_WAF)
(cd node-kstat && $(NODE_WAF) configure && $(NODE_WAF) build)
+node-expat/build/default/node-expat.node: node-expat/node-expat.cc $(NODE_WAF)
+ (cd node-expat && $(NODE_WAF) configure && $(NODE_WAF) build)
+
disklist:
cp disklist.sh disklist
chmod 0755 disklist
View
@@ -13,7 +13,9 @@ f usr/vm/sbin/vmadm 0555 root bin
f usr/vm/sbin/vmadmd 0555 root bin
f usr/vm/sbin/zoneevent 0555 root bin
f usr/vm/etc/vmadm.completion 0444 root bin
+f usr/vm/node_modules/expat_binding.node 0444 root bin
f usr/vm/node_modules/httpu.js 0444 root bin
+f usr/vm/node_modules/node-expat.js 0444 root bin
f usr/vm/node_modules/nopt.js 0444 root bin
f usr/vm/node_modules/qmp.js 0444 root bin
f usr/vm/node_modules/VM.js 0444 root bin
@@ -0,0 +1,4 @@
+.lock-wscript
+node_modules
+build
+*.swp
View
@@ -0,0 +1,20 @@
+Copyright (c) 2010 Stephan Maka
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
@@ -0,0 +1,49 @@
+# node-expat #
+
+## Motivation ##
+
+You use [node.js](http://github.com/ry/node) for speed? You process
+XML streams? Then you want the fastest XML parser: [libexpat](http://expat.sourceforge.net/)!
+
+## Speed ##
+
+A stupid speed test is supplied in `bench.js`. We measure how many
+25-byte elements a SAX parser can process:
+
+- [node-xml](http://github.com/robrighter/node-xml) (pure JavaScript): 23,000 el/s
+- [libxmljs](http://github.com/polotek/libxmljs) (libxml2 binding): 77,000 el/s
+- [node-expat](http://github.com/astro/node-expat) (libexpat binding, this): 113,000 el/s
+
+These numbers were recorded on a Core 2 2400 MHz and may turn out to
+be bullshit, given my few node.js experience.
+
+## Instructions ##
+
+ node-waf configure
+ node-waf build
+
+For using the library, make sure `build/default/expat.node` is in
+either `$NODE_PATH` or `require.paths`.
+
+Important events emitted by a parser:
+
+- *startElement* with `name, attrs`
+- *endElement* with `name`
+- *text* with `string`
+
+There are more. Use `test.js` for reference.
+
+It's possible to stop and resume the parser from within element handlers using the parsers
+stop() and resume() methods.
+
+## Error handling ##
+
+We don't emit an error event because libexpat doesn't use a callback
+either. Instead, check that `parse()` returns `true`. A descriptive
+string can be obtained via `getError()` to provide user feedback.
+
+## Namespace handling ##
+
+A word about special parsing of *xmlns:* this is not neccessary in a
+bare SAX parser like this, given that the DOM replacement you are
+using (if any) is not relevant to the parser.
View
@@ -0,0 +1,40 @@
+var sys = require('sys');
+var node_xml = require("node-xml");
+var libxml = require("libxmljs");
+var expat = require('./lib/node-expat');
+
+function NodeXmlParser() {
+ var parser = new node_xml.SaxParser(function(cb) { });
+ this.parse = function(s) {
+ parser.parseString(s);
+ };
+}
+function LibXmlJsParser() {
+ var parser = new libxml.SaxPushParser(function(cb) { });
+ this.parse = function(s) {
+ parser.push(s, false);
+ };
+}
+function ExpatParser() {
+ var parser = new expat.Parser();
+ this.parse = function(s) {
+ parser.parse(s, false);
+ };
+}
+
+//var p = new NodeXmlParser();
+//var p = new LibXmlJsParser();
+var p = new ExpatParser();
+p.parse("<r>");
+var nEl = 0;
+function d() {
+ p.parse("<foo bar='baz'>quux</foo>");
+ nEl++;
+ setTimeout(d, 0);
+}
+d();
+
+setInterval(function() {
+ sys.puts(nEl + " el/s");
+ nEl = 0;
+}, 1000);
@@ -0,0 +1,38 @@
+var EventEmitter = require('events').EventEmitter;
+var util = require('util');
+var expat = require('../build/default/node-expat');
+
+/**
+ * Simple wrapper because EventEmitter has turned pure-JS as of node
+ * 0.5.x.
+ */
+exports.Parser = function(encoding) {
+ this.parser = new expat.Parser(encoding);
+
+ var that = this;
+ this.parser.emit = function() {
+ that.emit.apply(that, arguments);
+ };
+};
+util.inherits(exports.Parser, EventEmitter);
+
+exports.Parser.prototype.parse = function(buf, isFinal) {
+ return this.parser.parse(buf, isFinal);
+};
+
+exports.Parser.prototype.setEncoding = function(encoding) {
+ return this.parser.setEncoding(encoding);
+};
+
+exports.Parser.prototype.getError = function() {
+ return this.parser.getError();
+};
+exports.Parser.prototype.stop = function() {
+ return this.parser.stop();
+};
+exports.Parser.prototype.pause = function() {
+ return this.stop();
+};
+exports.Parser.prototype.resume = function() {
+ return this.parser.resume();
+};
Oops, something went wrong.

0 comments on commit b1a52e5

Please sign in to comment.