Skip to content

Commit

Permalink
Added option for skipping null attribute values. Closes #26
Browse files Browse the repository at this point in the history
  • Loading branch information
oozcitak committed Dec 29, 2013
1 parent b398ec5 commit 509f6d1
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 27 deletions.
4 changes: 3 additions & 1 deletion src/XMLBuilder.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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
Expand Down
10 changes: 5 additions & 5 deletions src/XMLElement.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -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
Expand All @@ -53,7 +52,7 @@ module.exports = class XMLElement extends XMLNode
clonedChild = child.clone(deep)
clonedChild.parent = clonedSelf
clonedSelf.children.push clonedChild

return clonedSelf


Expand All @@ -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 @


Expand Down
1 change: 1 addition & 0 deletions src/XMLNode.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module.exports = class XMLNode
#
# `parent` the parent node
constructor: (@parent) ->
@options = @parent.options
@stringify = @parent.stringify


Expand Down
1 change: 1 addition & 0 deletions src/index.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
82 changes: 82 additions & 0 deletions test/attributes.coffee
Original file line number Diff line number Diff line change
@@ -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)

21 changes: 0 additions & 21 deletions test/removeattribute.coffee

This file was deleted.

0 comments on commit 509f6d1

Please sign in to comment.