Browse files

Added CDATA and mixed content support.

  • Loading branch information...
1 parent 770260e commit d40e8c5bdea95f2a7e493c7c12ccfdf06b7c46ee @lucsky committed Oct 5, 2013
Showing with 102 additions and 3 deletions.
  1. +29 −2 lib/exml.js
  2. +6 −0 test/fixtures/cdata.xml
  3. +6 −0 test/fixtures/mixed.xml
  4. +61 −1 test/test.js
View
31 lib/exml.js
@@ -1,7 +1,7 @@
var sax = require('sax');
function _newFrame() {
- return { handlers: {}, textContent: '' };
+ return { handlers: {}, textContent: '', cdataContent: '', content: '' };
}
function Parser() {
@@ -11,6 +11,7 @@ function Parser() {
this._stream = sax.createStream({ lowercase: true });
this._stream.on('opentag', this._handleOpenTag.bind(this));
this._stream.on('text', this._handleText.bind(this));
+ this._stream.on('cdata', this._handleCDATA.bind(this));
this._stream.on('closetag', this._handleCloseTag.bind(this));
}
@@ -41,8 +42,16 @@ Parser.prototype._handleOpenTag = function(node) {
};
Parser.prototype._handleCloseTag = function() {
+ this._eventStack.push('$content');
+
+ var handler = this._getHandler();
+ if (handler) {
+ handler(this._currentFrame().content);
+ }
+
this._frameStack.pop();
this._eventStack.pop();
+ this._eventStack.pop();
};
Parser.prototype._handleText = function(text) {
@@ -53,7 +62,25 @@ Parser.prototype._handleText = function(text) {
handler(text);
}
- this._currentFrame().textContent += text;
+ var currentFrame = this._currentFrame();
+ currentFrame.textContent += text;
+ currentFrame.content += text;
+
+ this._eventStack.pop();
+};
+
+Parser.prototype._handleCDATA = function(cdata) {
+ this._eventStack.push('$cdata');
+
+ var handler = this._getHandler();
+ if (handler) {
+ handler(cdata);
+ }
+
+ var currentFrame = this._currentFrame();
+ currentFrame.cdataContent += cdata;
+ currentFrame.content += cdata;
+
this._eventStack.pop();
};
View
6 test/fixtures/cdata.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<root>
+ <node><![CDATA[CDATA content 1]]></node>
+ <node><![CDATA[CDATA content 2]]></node>
+ <node><![CDATA[CDATA content 3]]></node>
+</root>
View
6 test/fixtures/mixed.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<root>
+ <node>Text content followed by some <![CDATA[CDATA content 1]]></node>
+ <node>Text content followed by some <![CDATA[CDATA content 2]]></node>
+ <node>Text content followed by some <![CDATA[CDATA content 3]]></node>
+</root>
View
62 test/test.js
@@ -2,7 +2,9 @@ var fs = require('fs');
var exml = require('../lib/exml');
var SIMPLE_XML = fs.readFileSync(__dirname + '/fixtures/simple.xml'),
- TEXT_XML = fs.readFileSync(__dirname + '/fixtures/text.xml');
+ TEXT_XML = fs.readFileSync(__dirname + '/fixtures/text.xml'),
+ CDATA_XML = fs.readFileSync(__dirname + '/fixtures/cdata.xml'),
+ MIXED_XML = fs.readFileSync(__dirname + '/fixtures/mixed.xml');
module.exports.exml = {
setUp: function(callback) {
@@ -75,5 +77,63 @@ module.exports.exml = {
this.parser.end(TEXT_XML);
test.done();
+ },
+
+ 'local cdata events': function(test) {
+ var parser = this.parser,
+ index = 1;
+
+ parser.on('root', function() {
+ var index = 1;
+ parser.on('node', function() {
+ parser.on('$cdata', function(cdata) {
+ test.equal(cdata, 'CDATA content ' + index);
+ index++
+ });
+ });
+ });
+
+ parser.end(CDATA_XML);
+ test.done();
+ },
+
+ 'stacked cdata events': function(test) {
+ var index = 1;
+ this.parser.on('root', 'node', '$cdata', function(text) {
+ test.equal(text, 'CDATA content ' + index);
+ index++
+ });
+
+ this.parser.end(CDATA_XML);
+ test.done();
+ },
+
+ 'local mixed content events': function(test) {
+ var parser = this.parser,
+ index = 1;
+
+ parser.on('root', function() {
+ var index = 1;
+ parser.on('node', function() {
+ parser.on('$content', function(content) {
+ test.equal(content, 'Text content followed by some CDATA content ' + index);
+ index++
+ });
+ });
+ });
+
+ parser.end(MIXED_XML);
+ test.done();
+ },
+
+ 'stacked mixed content events': function(test) {
+ var index = 1;
+ this.parser.on('root', 'node', '$content', function(content) {
+ test.equal(content, 'Text content followed by some CDATA content ' + index);
+ index++
+ });
+
+ this.parser.end(MIXED_XML);
+ test.done();
}
};

0 comments on commit d40e8c5

Please sign in to comment.