Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

added the XMLBuilder class

  • Loading branch information...
commit 2325ff18f0d0b1aa29ccc875dd3e92d7a3d99dfb 1 parent ff9b47f
@oozcitak authored
View
1  .gitignore
@@ -0,0 +1 @@
+lib/
View
10 Makefile
@@ -0,0 +1,10 @@
+dev:
+ @rm -fr lib/
+ @test `which coffee` || echo 'You need to have CoffeeScript installed.'
+ @coffee -c -o lib src/*.coffee
+
+publish: dev
+ @test `which npm` || echo 'You need to have npm installed.'
+ npm publish
+ @rm -fr lib/
+
View
25 package.json
@@ -0,0 +1,25 @@
+{ "name" : "xmlbuilder"
+, "version": "0.0.1"
+, "description": "An XML builder for node.js"
+, "author": "Ozgur Ozcitak <oozcitak@gmail.com>"
+, "licenses": [
+ {
+ "type": "MIT",
+ "url": "http://opensource.org/licenses/mit-license.php"
+ }
+ ]
+, "repositories": [
+ {
+ "type": "git",
+ "url": "git://github.com/oozcitak/xmlbuilder-js.git"
+ }
+ ]
+, "bugs": {
+ "web": "http://github.com/oozcitak/xmlbuilder-js/issues"
+ }
+, "directories": {
+ "lib": "./lib"
+ }
+, "dependencies": {}
+}
+
View
7 src/index.coffee
@@ -0,0 +1,7 @@
+module.exports =
+
+ builder: (options) ->
+ new @XMLBuilder options
+
+module.exports.__defineGetter__ 'XMLBuilder', ->
+ require './xmlbuilder'
View
139 src/xmlbuilder.coffee
@@ -0,0 +1,139 @@
+# xmlbuilder
+# ==========
+# An XML builder for node.js
+# Copyright Ozgur Ozcitak 2010
+# Licensed under the MIT license
+
+class XMLBuilder
+
+ decorators:
+ OpenTag: '<'
+ CloseTag: '>'
+ CloseSOTag: '/>'
+ AttDelim: '='
+ AttSep: ' '
+ Quote: '"'
+ Space: ' '
+ Indent: ' '
+
+ # Regular expressions to validate tokens
+ # See: http://www.w3.org/TR/xml/
+ # Supplementary Unicode code points not supported
+ validators:
+ Space:
+ "(?:\u0020|\u0009|\u000D|\u000A)+"
+ Char:
+ "\u0009|\u000A|\u000D|[\u0020-\uD7FF]|[\uE000-\uFFFD]"
+ NameStartChar:
+ ":|[A-Z]|_|[a-z]|[\u00C0-\u00D6]|[\u00D8-\u00F6]|[\u00F8-\u02FF]|" +
+ "[\u0370-\u037D]|[\u037F-\u1FFF]|[\u200C-\u200D]|[\u2070-\u218F]|[\u2C00-\u2FEF]|" +
+ "[\u3001-\uD7FF]|[\uF900-\uFDCF]|[\uFDF0-\uFFFD]"
+ NameChar:
+ ":|[A-Z]|_|[a-z]|[\u00C0-\u00D6]|[\u00D8-\u00F6]|[\u00F8-\u02FF]|" +
+ "[\u0370-\u037D]|[\u037F-\u1FFF]|[\u200C-\u200D]|[\u2070-\u218F]|[\u2C00-\u2FEF]|" +
+ "[\u3001-\uD7FF]|[\uF900-\uFDCF]|[\uFDF0-\uFFFD]" +
+ "-|\.|[0-9]|\u00B7|[\u0300-\u036F]|[\u203F-\u2040]"
+ CharRef:
+ "&#[0-9]+;|&#x[0-9a-fA-F]+;"
+ CharData:
+ "(?![^<&]*]]>[^<&]*)[^<&]*"
+
+ constructor: (options) ->
+ @reset ()
+
+ options or= { indent: false, validate: true };
+ @settings = {}
+ @settings.indent = options.indent or false
+ @settings.validate = options.validate or true
+
+ # build compound validation strings
+ @validators.Name = @validators.NameStartChar + '(?:' + @validators.NameChar + ')*'
+ @validators.NMToken = '(?:' + @validators.NameChar + ')+'
+ @validators.EntityRef = '&' + @validators.Name + ';'
+ @validators.Reference = @validators.EntityRef + '|' + @validators.CharRef
+ @validators.PEReference = '%' + @validators.Name + ';'
+ if @decorators.Quote == '"'
+ @validators.EntityValue = '(?:[^%&"]|%' + @validators.Name + ';|&' + @validators.Name + ';)*'
+ else
+ @validators.EntityValue = "'(?:[^%&']|%" + @validators.Name + ';|&' + @validators.Name + ';)*'
+ if @decorators.Quote == '"'
+ @validators.AttValue = '(?:[^<&"]|' + @validators.Reference + ')*'
+ else
+ @validators.AttValue = "(?:[^<&']|" + @validators.Reference + ')*'
+ if @decorators.Quote == '"'
+ @validators.SystemLiteral = '[^"]*'
+ else
+ @validators.SystemLiteral = "[^']*"
+ if @decorators.Quote == '"'
+ @validators.PubIDChar = "\u0020|\u000D|\u000A|[a-zA-Z0-9]|[-'()+,./:=?;!*#@$_%]"
+ else
+ @validators.PubIDChar = "\u0020|\u000D|\u000A|[a-zA-Z0-9]|[-()+,./:=?;!*#@$_%]"
+ @validators.PubIDLiteral = '(?:' + @validators.PubIDChar + ')*'
+ @validators.CommentChar = '(?!-)' + '(?:' + @validators.Char + ')'
+ @validators.Comment = '<!--' + '(?:' + @validators.CommentChar + '|' +
+ '-' + @validators.CommentChar + ')*' + '-->'
+
+ reset: () =>
+ @elements = []
+ @level = 0
+
+ prolog: () =>
+ # FIXME
+ @elements.push '<?xml version="1.0"?>'
+
+ element: (name, attributes, callback) =>
+ value = undefined
+ if typeof callback is "string"
+ value = callback
+ callback = undefined
+
+ # open tag
+ if not name?
+ throw new Error "Missing element name"
+ if @settings.validate and not name.match "^" + @validators.Name + "$"
+ throw new Error "Invalid element name: " + name
+ @elements.push @decorators.OpenTag + name
+
+ # attributes
+ if attributes?
+ for attName, attValue of attributes
+ if @settings.validate and not attName.match "^" + @validators.Name + "$"
+ throw new Error "Invalid attribute name: " + attName
+ if @settings.validate and not attValue.match "^" + @validators.AttValue + "$"
+ throw new Error "Invalid attribute value: " + attValue
+ @elements.push @decorators.Space + attName + @decorators.Equals +
+ @decorators.Quote + attValue + @decorators.Quote
+
+ # value or inner tags
+ if value?
+ if @settings.validate and not value.match "^" + @validators.EntityValue + "$"
+ throw new Error "Invalid element value: " + value
+ @elements.push value
+ else if callback?
+ callback
+
+ # close tag
+ if value? or callback?
+ @elements.push @decorators.CloseTag
+ else
+ @elements.push @decorators.CloseSOTag
+
+ text: (value) =>
+ if not value?
+ throw new Error "Missing text value"
+ if @settings.validate and not value.match "^" + @validators.EntityValue + "$"
+ throw new Error "Invalid text value: " + value
+ @elements.push value
+
+ toString: ->
+ r = ""
+ for e in @elements
+ r += e
+ return r
+
+ # aliases
+ pro: () => @prolog
+ ele: (name, attributes, callback) => @element name, attributes, callback
+ txt: (value) => @text value
+
+module.exports = XMLBuilder
Please sign in to comment.
Something went wrong with that request. Please try again.