Browse files

First commit

  • Loading branch information...
0 parents commit a96dbe028e59d8a0c9bfb486475b0a1a24e51059 @dylang committed Apr 11, 2011
Showing with 410 additions and 0 deletions.
  1. +22 −0 LICENSE
  2. +1 −0 README
  3. +49 −0 examples/examples.js
  4. +1 −0 index.js
  5. +16 −0 lib/util.js
  6. +101 −0 lib/xml.js
  7. +30 −0 package.json
  8. +124 −0 readme.md
  9. +66 −0 test/test.js
22 LICENSE
@@ -0,0 +1,22 @@
+(The MIT License)
+
+Copyright (c) 2011 Dylan Greene <dylang@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1 README
@@ -0,0 +1 @@
+This file was created by JetBrains WebStorm 2.0.1 for binding GitHub repository
49 examples/examples.js
@@ -0,0 +1,49 @@
+var XML = require('xml');
+
+
+var example1 = { url: 'http://www.google.com/search?aq=f&sourceid=chrome&ie=UTF-8&q=opower' };
+console.log(XML(example1));
+//<url>http://www.google.com/search?aq=f&amp;sourceid=chrome&amp;ie=UTF-8&amp;q=opower</url>
+
+var example2 = [ { url: { _attr: { hostname: 'www.google.com', path: '/search?aq=f&sourceid=chrome&ie=UTF-8&q=opower' } } } ];
+console.log(XML(example2));
+//<url hostname="www.google.com" path="/search?aq=f&amp;sourceid=chrome&amp;ie=UTF-8&amp;q=opower"/>
+
+var example3 = [ { toys: [ { toy: 'Transformers' } , { toy: 'GI Joe' }, { toy: 'He-man' } ] } ];
+console.log(XML(example3));
+//<toys><toy>Transformers</toy><toy>GI Joe</toy><toy>He-man</toy></toys>
+console.log(XML(example3, true));
+/*
+<toys>
+ <toy>Transformers</toy>
+ <toy>GI Joe</toy>
+ <toy>He-man</toy>
+</toys>
+*/
+
+var example4 = [ { toys: [ { _attr: { decade: '80s', locale: 'US'} }, { toy: 'Transformers' } , { toy: 'GI Joe' }, { toy: 'He-man' } ] } ];
+console.log(XML(example4, true));
+/*
+<toys decade="80s" locale="US">
+ <toy>Transformers</toy>
+ <toy>GI Joe</toy>
+ <toy>He-man</toy>
+</toys>
+*/
+
+var example5 = [ { toys: [ { _attr: { decade: '80s', locale: 'US'} }, { toy: 'Transformers' } , { toy: 'GI Joe' }, { toy: [ { name: 'He-man' }, { description: { _cdata: '<strong>Master of the Universe!</strong>'} } ] } ] } ];
+console.log(XML(example5, true));
+/*
+<toys decade="80s" locale="US">
+ <toy>Transformers</toy>
+ <toy>GI Joe</toy>
+ <toy>
+ <name>He-man</name>
+ <description>
+<![CDATA[
+<strong>Master of the Universe!</strong>
+]]>
+ </description>
+ </toy>
+</toys>
+*/
1 index.js
@@ -0,0 +1 @@
+module.exports = require('./lib/xml');
16 lib/util.js
@@ -0,0 +1,16 @@
+
+var XML_CHARACTER_MAP = {
+ '&': '&amp;',
+ '"': '&quot;',
+ '<': '&lt;',
+ '>': '&gt;'
+};
+
+function xml_safe(string) {
+ return string && string.replace ? string.replace(/([&"<>])/g, function(str, item) {
+ return XML_CHARACTER_MAP[item];
+ })
+ : string;
+}
+
+module.exports.xml_safe = xml_safe;
101 lib/xml.js
@@ -0,0 +1,101 @@
+var util = require('./util');
+
+var DEFAULT_INDENT = ' ';
+
+function xml (input, indent) {
+ var output = [];
+
+ indent = !indent ? '' : indent === true ? DEFAULT_INDENT : indent;
+
+ if (input && input.forEach) {
+ input.forEach(function(value){
+ output.push(resolve(value, indent, indent ? 1 : 0));
+ });
+ } else {
+ output.push(resolve(input, indent, indent ? 1 : 0));
+ }
+ return output.join(indent ? '\n' : '');
+}
+
+function resolve(data, indent, indent_count) {
+ indent_count = indent_count || 0;
+ var indent_spaces = (new Array(indent_count).join(indent));
+ var name;
+ var values = data;
+
+ if (typeof data == 'object') {
+ var keys = Object.keys(data);
+ name = keys[0];
+ values = data[name];
+ }
+
+ var attributes = [],
+ content = [];
+
+ function get_attributes(obj){
+ var keys = Object.keys(obj);
+ keys.forEach(function(key){
+ attributes.push(attribute(key, obj[key]));
+ });
+
+ }
+
+ switch(typeof values) {
+ case 'object':
+ if (values._attr) {
+ get_attributes(values._attr);
+ }
+
+ if (values._cdata) {
+ content.push('');
+ content.push('<![CDATA[');
+ content.push(values._cdata);
+ content.push(']]>');
+ content.push('');
+ }
+
+ if (values.forEach) {
+ content.push('');
+
+ values.forEach(function(value) {
+ if (typeof value == 'object') {
+ var _name = Object.keys(value)[0];
+
+ if (_name == '_attr') {
+ get_attributes(value._attr);
+ } else {
+ content.push(resolve(value, indent, indent_count + 1));
+ }
+ } else {
+ //string
+ content.push(util.xml_safe(value));
+ }
+
+ });
+ content.push('');
+ }
+ break;
+
+ default:
+ //string
+ content.push(util.xml_safe(values));
+
+ }
+
+ return indent_spaces
+ + (name ? '<' + name : '')
+ + (attributes.length ? ' '
+ + attributes.join(' ')
+ : '')
+ + (content.length ? (name ? '>' : '')
+ + content.join(indent ? '\n' : '')
+ + (content.length > 1 ? indent_spaces : '')
+ + (name ? '</' + name + '>' : '')
+ : (name ? '/>' : ''));
+}
+
+function attribute(key, value) {
+ return key + '=' + '"' + util.xml_safe(value) + '"';
+}
+
+module.exports = xml;
30 package.json
@@ -0,0 +1,30 @@
+{
+ "name": "xml",
+ "version": "0.0.2",
+ "description": "Fast and simple xml generator. Supports attributes, CDATA, etc. Tests and examples.",
+ "homepage": "http://github.com/dylang/node-xml",
+ "author": "Dylan Greene <dylang@gmail.com>",
+ "contributors": [
+ "Dylan Greene <dylang@gmail.com>"
+ ],
+ "repository":
+ {
+ "type": "git",
+ "url": "http://github.com/dylang/node-xml"
+ },
+ "bugs":
+ {
+ "mail": "dylang@gmail.com",
+ "web": "http://github.com/dylang/node-xml/issues"
+ },
+ "dependencies":
+ {
+ "logging": ">= 2.0.0"
+ },
+ "main": "index.js",
+ "engines": { "node": ">=0.4.0" },
+ "licenses" :
+ [
+ { "type" : "MIT", "url" : "http://github.com/dylang/node-xml/raw/master/LICENSE" }
+ ]
+}
124 readme.md
@@ -0,0 +1,124 @@
+# XML for Node
+
+ Fast and simple Javascript-based XML generator/builder for Node projects.
+
+## Install
+
+ $ npm install xml
+
+## Examples
+
+ There are examples in the examples directory.
+
+## Tests
+
+ Use [nodeunit](https://github.com/caolan/nodeunit) to run the tests.
+
+ $ npm install nodeunit
+ $ nodeunit test
+
+Everything should pass:
+
+ test
+ ? empty
+ ? simple
+ ? deep
+ ? indent
+ ? attributes
+ ? cdata
+ ? encoding
+
+ OK: 30 assertions (4ms)
+
+## API
+ XML(object, [indent])
+
+ * __object__ See Usage for how this can work.
+ * __indent__ Falsy value: No indent or line breaks (default). True: 4 spaces. '\t': Single tab. ' ': Two spaces. Etc.
+
+## Usage
+
+ var XML = require('xml');
+
+ var example1 = [ { url: 'http://www.google.com/search?aq=f&sourceid=chrome&ie=UTF-8&q=opower' } ];
+ console.log(XML(example1));
+ //<url>http://www.google.com/search?aq=f&amp;sourceid=chrome&amp;ie=UTF-8&amp;q=opower</url>
+
+ var example2 = [ { url: { _attr: { hostname: 'www.google.com', path: '/search?aq=f&sourceid=chrome&ie=UTF-8&q=opower' } } } ];
+ console.log(XML(example2));
+ //<url hostname="www.google.com" path="/search?aq=f&amp;sourceid=chrome&amp;ie=UTF-8&amp;q=opower"/>
+
+ var example3 = [ { toys: [ { toy: 'Transformers' } , { toy: 'GI Joe' }, { toy: 'He-man' } ] } ];
+ console.log(XML(example3));
+ //<toys><toy>Transformers</toy><toy>GI Joe</toy><toy>He-man</toy></toys>
+ console.log(XML(example3, true));
+ /*
+ <toys>
+ <toy>Transformers</toy>
+ <toy>GI Joe</toy>
+ <toy>He-man</toy>
+ </toys>
+ */
+
+ var example4 = [ { toys: [ { _attr: { decade: '80s', locale: 'US'} }, { toy: 'Transformers' } , { toy: 'GI Joe' }, { toy: 'He-man' } ] } ];
+ console.log(XML(example4, true));
+ /*
+ <toys decade="80s" locale="US">
+ <toy>Transformers</toy>
+ <toy>GI Joe</toy>
+ <toy>He-man</toy>
+ </toys>
+ */
+
+ var example5 = [ { toys: [ { _attr: { decade: '80s', locale: 'US'} }, { toy: 'Transformers' } , { toy: 'GI Joe' }, { toy: [ { name: 'He-man' }, { description: { _cdata: '<strong>Master of the Universe!</strong>'} } ] } ] } ];
+ console.log(XML(example5, true));
+ /*
+ <toys decade="80s" locale="US">
+ <toy>Transformers</toy>
+ <toy>GI Joe</toy>
+ <toy>
+ <name>He-man</name>
+ <description>
+ <![CDATA[
+ <strong>Master of the Universe!</strong>
+ ]]>
+ </description>
+ </toy>
+ </toys>
+ */
+
+
+## Keywords
+
+ * ___atr__: set attributes using a hash of key/value pairs.
+ * ___cdata__: Value of _cdata is wrapped in xml CDATA so the data does not need to be escaped.
+
+
+# Contributing
+
+Contributions to the project are most welcome, so feel free to fork and improve.
+
+# License
+
+(The MIT License)
+
+Copyright (c) 2011 Dylan Greene <dylang@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
66 test/test.js
@@ -0,0 +1,66 @@
+/*
+ Use nodeunit to run tests
+*/
+
+var XML = require('../index');
+
+
+module.exports = {
+
+ empty: function(test) {
+ test.equal(XML(), '');
+ test.equal(XML([]), '');
+ test.equal(XML('test'), 'test');
+ test.equal(XML('test'), 'test');
+ test.equal(XML('scotch & whisky'), 'scotch &amp; whisky');
+ test.done();
+ },
+
+
+ simple: function(test) {
+ test.equal(XML([ { a: {} }]), '<a/>');
+ test.equal(XML([ { a: [] }]), '<a></a>');
+ test.equal(XML([ { a: -1 }]), '<a>-1</a>');
+ test.equal(XML([ { a: false }]), '<a>false</a>');
+ test.equal(XML([ { a: 'test' }]), '<a>test</a>');
+ test.equal(XML( { a: {} }), '<a/>');
+ test.equal(XML( { a: [] }), '<a></a>');
+ test.equal(XML( { a: -1 }), '<a>-1</a>');
+ test.equal(XML( { a: false }), '<a>false</a>');
+ test.equal(XML( { a: 'test' }), '<a>test</a>');
+ test.equal(XML([ { a: 'test' }, { b: 123 }, { c: -0.5 } ]), '<a>test</a><b>123</b><c>-0.5</c>');
+ test.done();
+ },
+
+ deep: function(test) {
+ test.equal(XML([ { a: [ { b: [ { c: 1 }, { c: 2 }, { c: 3 } ] } ] }]), '<a><b><c>1</c><c>2</c><c>3</c></b></a>');
+ test.done();
+ },
+
+ indent: function(test) {
+ test.equal(XML([ { a: [ { b: [ { c: 1 }, { c: 2 }, { c: 3 } ] } ] }], true), '<a>\n <b>\n <c>1</c>\n <c>2</c>\n <c>3</c>\n </b>\n</a>');
+ test.equal(XML([ { a: [ { b: [ { c: 1 }, { c: 2 }, { c: 3 } ] } ] }], ' '), '<a>\n <b>\n <c>1</c>\n <c>2</c>\n <c>3</c>\n </b>\n</a>');
+ test.equal(XML([ { a: [ { b: [ { c: 1 }, { c: 2 }, { c: 3 } ] } ] }], '\t'), '<a>\n\t<b>\n\t\t<c>1</c>\n\t\t<c>2</c>\n\t\t<c>3</c>\n\t</b>\n</a>');
+ test.done();
+ },
+
+
+ attributes: function(test) {
+ test.equal(XML([ { b: { _attr: {} } } ]), '<b/>');
+ test.equal(XML([ { a: { _attr: { attribute1: 'some value', attribute2: 12345 } } } ]), '<a attribute1="some value" attribute2="12345"/>');
+ test.equal(XML([ { a: [{ _attr: { attribute1: 'some value', attribute2: 12345 } }] } ]), '<a attribute1="some value" attribute2="12345"></a>');
+ test.done();
+ },
+
+ cdata: function(test) {
+ test.equal(XML([ { a: { _cdata: 'This is some <strong>CDATA</strong>' } } ]), '<a><![CDATA[This is some <strong>CDATA</strong>]]></a>');
+ test.equal(XML([ { a: { _attr: { attribute1: 'some value', attribute2: 12345 }, _cdata: 'This is some <strong>CDATA</strong>' } } ]), '<a attribute1="some value" attribute2="12345"><![CDATA[This is some <strong>CDATA</strong>]]></a>');
+ test.done();
+ },
+
+ encoding: function(test) {
+ test.equal(XML([ { a: [ { _attr: { anglebrackets: 'this is <strong>strong</strong>', url: 'http://google.com?s=opower&y=fun' } }, 'text'] } ]), '<a anglebrackets="this is &lt;strong&gt;strong&lt;/strong&gt;" url="http://google.com?s=opower&amp;y=fun">text</a>');
+ test.done();
+ }
+
+};

0 comments on commit a96dbe0

Please sign in to comment.