Skip to content
Browse files

Implemented recording of XML, sort of

  • Loading branch information...
1 parent 7f90763 commit 8769ec312a9f3f4b0ddf1b7e4d7996dad2f6de86 @StevenLooman committed Aug 16, 2012
Showing with 104 additions and 112 deletions.
  1. +0 −99 lib/dom_recorder.js
  2. +16 −13 lib/saxpath.js
  3. +82 −0 lib/xml_recorder.js
  4. +6 −0 run.js
View
99 lib/dom_recorder.js
@@ -1,99 +0,0 @@
-var debug = false;
-function trace(message) {
- if (debug) {
- console.log(message);
- }
-}
-
-
-/**
- * XML DOM recorder
- */
-function DomRecorder() {
- this.recording = false;
-
-// this.document = null;
-// this.currentNode = null;
-}
-
-
-/**
- * Start recording
- */
-DomRecorder.prototype.start = function() {
- trace('start recording');
-
- this.recording = true;
-
-// this.document = new Document();
-// this.currentNode = this.document.docElement;
-};
-
-/**
- * Stop recording
- */
-DomRecorder.prototype.stop = function() {
- trace('stop recording');
-
- this.recording = false;
-
-// this.emit('match', this.document);
-// this.document = null;
-// this.currentNode = null;
-};
-
-DomRecorder.prototype.isRecording = function() {
- return this.recording;
-};
-
-
-/**
- * Event handlers for SAX-stream
- */
-DomRecorder.prototype.onOpenTag = function(node) {
- if (!this.recording) {
- return;
- }
-
- trace('record open tag');
-
-// var e = new Element(node.name);
-//
-// this.currentNode.appendChild(e);
-// for (var key in node.attributes) {
-// var value = node.attributes[key];
-// e.setAttribute(key, value);
-// }
-//
-// this.currentNode = e;
-};
-
-/**
- * Event handlers for SAX-stream
- */
-DomRecorder.prototype.onCloseTag = function(tag) {
- if (!this.recording) {
- return;
- }
-
- trace('record close tag');
-
-// this.currentNode = this.currentNode.parentNode;
-};
-
-/**
- * Event handlers for SAX-stream
- */
-DomRecorder.prototype.onText = function(text) {
- if (!this.recording) {
- return;
- }
-
- trace('record text');
-
-// var e = new TextNode(test);
-// this.currentNode.appendChild(e);
-};
-
-
-module.exports = DomRecorder;
View
29 lib/saxpath.js
@@ -2,12 +2,13 @@ var util = require('util');
var events = require('events');
var XPathParser = require('./xpath_parser');
-var DomRecorder = require('./dom_recorder');
+var XmlRecorder = require('./xml_recorder');
var StartState = require('./start_state');
var ChildState = require('./child_state');
var SelfOrDescendantState = require('./self_or_descendant_state');
+
var debug = false;
function trace(depth, message) {
var i;
@@ -27,22 +28,22 @@ function trace(depth, message) {
* Does so by building a state machine and feeding nodes as input to it.
*/
function SaXPath(saxParser, xpath, recorder) {
+ this.saxParser = saxParser;
this.currentDepth = 0;
- this.saxParser = saxParser;
-
- this.saxParser.on('opentag' , this.onOpenTag.bind(this));
- this.saxParser.on('closetag' , this.onCloseTag.bind(this));
- this.saxParser.on('end' , this.onEnd.bind(this));
-
- this.recorder = recorder || new Recorder();
- this.saxParser.on('opentag' , this.recorder.onOpenTag.bind(this.recorder));
- this.saxParser.on('closetag' , this.recorder.onCloseTag.bind(this.recorder));
- this.saxParser.on('text' , this.recorder.onText.bind(this.recorder));
-
this.xpathExpr = XPathParser.parse(xpath);
var states = this._parseXPathExpr(this.xpathExpr);
this.currentState = states[0];
+
+ this.recorder = recorder || new XmlRecorder();
+ // order of binding is important here!
+ // if the recorder is disabled too early, the node/tag will not be recorded!
+ this.saxParser.on('opentag', this.onOpenTag.bind(this));
+ this.saxParser.on('opentag', this.recorder.onOpenTag.bind(this.recorder));
+ this.saxParser.on('closetag', this.recorder.onCloseTag.bind(this.recorder));
+ this.saxParser.on('closetag', this.onCloseTag.bind(this));
+ this.saxParser.on('text', this.recorder.onText.bind(this.recorder));
+ this.saxParser.on('end', this.onEnd.bind(this));
}
@@ -133,7 +134,9 @@ SaXPath.prototype.onCloseTag = function(tag) {
if (state.unmatches(tag, this.currentDepth)) {
// if we are at the top of the state-stack, stop the recorder
if (stopRecorder) {
- this.recorder.stop();
+ var xml = this.recorder.stop();
+
+ this.emit('match', xml);
}
// hop to previous state
View
82 lib/xml_recorder.js
@@ -0,0 +1,82 @@
+var debug = false;
+function trace(message) {
+ if (debug) {
+ console.log(message);
+ }
+}
+
+
+/**
+ * XML DOM recorder
+ */
+function XmlRecorder() {
+ this.recording = false;
+}
+
+
+/**
+ * Start recording
+ */
+XmlRecorder.prototype.start = function() {
+ trace('start recording');
+
+ this.recording = true;
+ this.str = '';
+};
+
+/**
+ * Stop recording
+ */
+XmlRecorder.prototype.stop = function() {
+ trace('stop recording');
+
+ this.recording = false;
+ return this.str;
+};
+
+XmlRecorder.prototype.isRecording = function() {
+ return this.recording;
+};
+
+
+/**
+ * Event handlers for SAX-stream
+ */
+XmlRecorder.prototype.onOpenTag = function(node) {
+ if (!this.recording) {
+ return;
+ }
+
+ trace('record open tag');
+
+ this.str += '<' + node.name + '>';
+};
+
+/**
+ * Event handlers for SAX-stream
+ */
+XmlRecorder.prototype.onCloseTag = function(tag) {
+ if (!this.recording) {
+ return;
+ }
+
+ trace('record close tag');
+
+ this.str += '</' + tag + '>';
+};
+
+/**
+ * Event handlers for SAX-stream
+ */
+XmlRecorder.prototype.onText = function(text) {
+ if (!this.recording) {
+ return;
+ }
+
+ trace('record text');
+
+ this.str += text;
+};
+
+
+module.exports = XmlRecorder;
View
6 run.js
@@ -6,12 +6,18 @@ var xps = require('./lib');
var filename = 'test/bookstore.xml';
+function onMatch(xml) {
+ console.log(xml);
+}
+
function main() {
var saxParser = sax.createStream(true);
// var streamer = new xps.SaXPath(saxParser, '/bookstore/book');
// var streamer = new xps.SaXPath(saxParser, '/bookstore/book[@category="COOKING"]');
var streamer = new xps.SaXPath(saxParser, '//book');
+ streamer.on('match', onMatch);
+
var fileStream = fs.createReadStream(filename);
fileStream.pipe(saxParser);
}

0 comments on commit 8769ec3

Please sign in to comment.
Something went wrong with that request. Please try again.