diff --git a/README.md b/README.md
index afcd3f3d..283c9313 100644
--- a/README.md
+++ b/README.md
@@ -106,6 +106,9 @@ Settings supported:
* `strictEntities` - Boolean. If true, only parse [predefined XML
entities](http://www.w3.org/TR/REC-xml/#sec-predefined-ent)
(`&`, `'`, `>`, `<`, and `"`)
+* `emitEmpty` - Boolean. If true, then SAX will emit `cdata` and `comment`
+ events even if the CDATA section or comment were empty. By default,
+ when these XML structures are empty, SAX does not emit an event.
## Methods
diff --git a/lib/sax.js b/lib/sax.js
index 795d607e..4b960b6a 100644
--- a/lib/sax.js
+++ b/lib/sax.js
@@ -61,6 +61,7 @@
parser.noscript = !!(strict || parser.opt.noscript)
parser.state = S.BEGIN
parser.strictEntities = parser.opt.strictEntities
+ parser.emitEmpty = parser.opt.emitEmpty
parser.ENTITIES = parser.strictEntities ? Object.create(sax.XML_ENTITIES) : Object.create(sax.ENTITIES)
parser.attribList = []
@@ -140,6 +141,9 @@
function flushBuffers (parser) {
closeText(parser)
+ // We do not need to check emitEmpty here. We are guaranteed
+ // to produce a cdata event with an empty string when the cdata
+ // section ends.
if (parser.cdata !== '') {
emitNode(parser, 'oncdata', parser.cdata)
parser.cdata = ''
@@ -1180,7 +1184,7 @@
if (c === '-') {
parser.state = S.COMMENT_ENDED
parser.comment = textopts(parser.opt, parser.comment)
- if (parser.comment) {
+ if (parser.emitEmpty || parser.comment) {
emitNode(parser, 'oncomment', parser.comment)
}
parser.comment = ''
@@ -1221,7 +1225,7 @@
case S.CDATA_ENDING_2:
if (c === '>') {
- if (parser.cdata) {
+ if (parser.emitEmpty || parser.cdata) {
emitNode(parser, 'oncdata', parser.cdata)
}
emitNode(parser, 'onclosecdata')
diff --git a/test/emit_empty.js b/test/emit_empty.js
new file mode 100644
index 00000000..8c5bddb4
--- /dev/null
+++ b/test/emit_empty.js
@@ -0,0 +1,47 @@
+var xml = ''
+require(__dirname).test({
+ xml: xml,
+ expect: [
+ ['opentagstart', {'name': 'R', 'attributes': {}}],
+ ['opentag', {'name': 'R', 'attributes': {}, 'isSelfClosing': false}],
+ ['opencdata', undefined],
+ ['closecdata', undefined],
+ ['closetag', 'R']
+ ]
+})
+
+require(__dirname).test({
+ xml: xml,
+ opt: { emitEmpty: true },
+ expect: [
+ ['opentagstart', {'name': 'R', 'attributes': {}}],
+ ['opentag', {'name': 'R', 'attributes': {}, 'isSelfClosing': false}],
+ ['opencdata', undefined],
+ ['cdata', ''],
+ ['closecdata', undefined],
+ ['comment', ''],
+ ['closetag', 'R']
+ ]
+})
+
+// The following test illustrates an effect of emitEmpty together with
+// hitting the buffer limit. Namely, a trailing cdata event with an
+// empty string will be emitted after the buffer is emptied.
+var sax = require('../lib/sax')
+var bl = sax.MAX_BUFFER_LENGTH
+sax.MAX_BUFFER_LENGTH = 10
+require(__dirname).test({
+ opt: { emitEmpty: true },
+ expect: [
+ ['opentagstart', {'name': 'R', 'attributes': {}}],
+ ['opentag', {'name': 'R', 'attributes': {}, 'isSelfClosing': false}],
+ ['opencdata', undefined],
+ ['cdata', '12345678901'],
+ ['cdata', ''],
+ ['closecdata', undefined],
+ ['closetag', 'R']
+ ]
+}).write('')
+
+sax.MAX_BUFFER_LENGTH = bl