Permalink
Browse files

Added option for skipping null attribute values. Closes #26

  • Loading branch information...
oozcitak committed Dec 29, 2013
1 parent b398ec5 commit 509f6d1d12621162065d4062e0a8a1238d991f07
Showing with 92 additions and 27 deletions.
  1. +3 −1 src/XMLBuilder.coffee
  2. +5 −5 src/XMLElement.coffee
  3. +1 −0 src/XMLNode.coffee
  4. +1 −0 src/index.coffee
  5. +82 −0 test/attributes.coffee
  6. +0 −21 test/removeattribute.coffee
View
@@ -23,12 +23,14 @@ module.exports = class XMLBuilder
#
# `options.headless` whether XML declaration and doctype will be included: true or false
# `options.allowSurrogateChars` whether surrogates will be allowed: true or false
+ # `options.skipNullAttributes` whether attributes with null values will be ignored: true or false
# `options.stringify` a set of functions to use for converting values to strings
constructor: (name, options) ->
if not name?
throw new Error "Root element needs a name"
options ?= {}
+ @options = options
@stringify = new XMLStringifier options
temp = new XMLElement @, 'doc' # temporary node so that we can call element()
@@ -42,7 +44,7 @@ module.exports = class XMLBuilder
root.declaration options
if options.pubID? or options.sysID?
- root.doctype options.pubID, options.sysID
+ root.doctype options
# Gets the root node
View
@@ -15,7 +15,7 @@ module.exports = class XMLElement extends XMLNode
# `attributes` an object containing name/value pairs of attributes
constructor: (parent, name, attributes) ->
super parent
-
+
if not name?
throw new Error "Missing element name"
@@ -25,8 +25,7 @@ module.exports = class XMLElement extends XMLNode
@attributes = {}
for own attName, attValue of attributes
- if attName? and attValue?
- @attributes[attName] = new XMLAttribute @, attName, attValue
+ @attribute attName, attValue
# Clones self
@@ -53,7 +52,7 @@ module.exports = class XMLElement extends XMLNode
clonedChild = child.clone(deep)
clonedChild.parent = clonedSelf
clonedSelf.children.push clonedChild
-
+
return clonedSelf
@@ -63,7 +62,8 @@ module.exports = class XMLElement extends XMLNode
# `value` attribute value
attribute: (name, value) ->
value = value.apply() if _.isFunction value
- @attributes[name] = new XMLAttribute @, name, value
+ if not @options.skipNullAttributes or value?
+ @attributes[name] = new XMLAttribute @, name, value
return @
View
@@ -8,6 +8,7 @@ module.exports = class XMLNode
#
# `parent` the parent node
constructor: (@parent) ->
+ @options = @parent.options
@stringify = @parent.stringify
View
@@ -15,6 +15,7 @@ XMLBuilder = require './XMLBuilder'
#
# `options.headless` whether XML declaration and doctype will be included: true or false
# `options.allowSurrogateChars` whether surrogates will be allowed: true or false
+# `options.skipNullAttributes` whether attributes with null values will be ignored: true or false
# `options.stringify` a set of functions to use for converting values to strings
module.exports.create = (name, xmldec, doctype, options) ->
options = _.extend { }, xmldec, doctype, options
View
@@ -0,0 +1,82 @@
+vows = require 'vows'
+assert = require 'assert'
+
+xmlbuilder = require '../src/index.coffee'
+
+vows
+ .describe('Editing')
+ .addBatch
+ 'Add attribute':
+ topic: () ->
+ xmlbuilder.create('test4', { headless: true })
+ .ele('node', 'element', {"first":"1", "second":"2"})
+ .att("third", "3")
+
+ 'resulting XML': (doc) ->
+ xml = '<test4><node first="1" second="2" third="3">element</node></test4>'
+ assert.strictEqual doc.end(), xml
+
+ 'Remove attribute':
+ topic: () ->
+ root = xmlbuilder.create('test4', { headless: true })
+ ele = root.ele('node', 'element', {"first":"1", "second":"2", "third":"3"})
+ ele.removeAttribute("second")
+ root
+
+ 'resulting XML': (doc) ->
+ xml = '<test4><node first="1" third="3">element</node></test4>'
+ assert.strictEqual doc.end(), xml
+
+ 'Throw if null attribute (ele)':
+ topic: () ->
+ xmlbuilder.create('test4', { headless: true })
+
+ 'resulting XML': (root) ->
+ assert.throws ->
+ root.ele('node', 'element', {"first":null, "second":"2"})
+
+ 'Throw if null attribute (att)':
+ topic: () ->
+ xmlbuilder.create('test4', { headless: true })
+
+ 'resulting XML': (root) ->
+ assert.throws ->
+ root.ele('node').att("first")
+
+ 'Throw if null attribute (JSON)':
+ topic: () ->
+ xmlbuilder.create('test4', { headless: true })
+
+ 'resulting XML': (root) ->
+ assert.throws ->
+ root.ele({'@first': null})
+
+ 'Skip if null attribute (ele)':
+ topic: () ->
+ xmlbuilder.create('test4', { headless: true, skipNullAttributes: true })
+ .ele('node', 'element', {"first":null, 'second': '2'})
+
+ 'resulting XML': (doc) ->
+ xml = '<test4><node second="2">element</node></test4>'
+ assert.strictEqual doc.end(), xml
+
+ 'Skip if null attribute (att)':
+ topic: () ->
+ xmlbuilder.create('test4', { headless: true, skipNullAttributes: true })
+ .ele('node').att("first")
+
+ 'resulting XML': (doc) ->
+ xml = '<test4><node/></test4>'
+ assert.strictEqual doc.end(), xml
+
+ 'Skip if null attribute (JSON)':
+ topic: () ->
+ xmlbuilder.create('test4', { headless: true, skipNullAttributes: true })
+ .ele({'@first': null, '@second': '2'})
+
+ 'resulting XML': (doc) ->
+ xml = '<test4 second="2"/>'
+ assert.strictEqual doc.end(), xml
+
+ .export(module)
+
@@ -1,21 +0,0 @@
-vows = require 'vows'
-assert = require 'assert'
-
-xmlbuilder = require '../src/index.coffee'
-
-vows
- .describe('Editing')
- .addBatch
- 'Remove item':
- topic: () ->
- root = xmlbuilder.create('test4', {}, {}, { headless: true })
- ele = root.e('node', 'element', {"first":"1", "second":"2", "third":"3"})
- ele.removeAttribute("second")
- root
-
- 'resulting XML': (topic) ->
- xml = '<test4><node first="1" third="3">element</node></test4>'
- assert.strictEqual topic.end(), xml
-
- .export(module)
-

0 comments on commit 509f6d1

Please sign in to comment.