├── .gitignore ├── .travis.yml ├── Makefile ├── package.json ├── lib ├── js2xml.coffee └── js2xml.js ├── LICENSE ├── test └── js2xml_test.coffee └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: "node_js" 2 | node_js: 3 | - 4 4 | - 5 5 | - 6 6 | - 7 7 | - 8 8 | 9 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | JS=lib/js2xml.js 2 | 3 | all: $(JS) 4 | 5 | clean: 6 | -rm -f $(JS) 7 | 8 | %.js: %.coffee 9 | coffee -b -c $< 10 | 11 | test: $(JS) 12 | coffee test/js2xml_test.coffee 13 | 14 | .PHONY: clean test 15 | 16 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "Phil Jackson (http://apiaxle.com)", 3 | "name": "js2xml", 4 | "description": "Convert arbitary javascript to simple XML. Developed for ApiAxle.", 5 | "version": "1.0.9", 6 | "main": "./lib/js2xml", 7 | "license": "MIT", 8 | "repository": { 9 | "url": "https://github.com/philjackson/js2xml" 10 | }, 11 | "keywords": [ 12 | "xml", 13 | "json", 14 | "json2xml", 15 | "js2xml", 16 | "data2xml", 17 | "data", 18 | "libxml" 19 | ], 20 | "licenses": [ 21 | { 22 | "type": "MIT", 23 | "url": "http://github.com/jashkenas/coffee-script/raw/master/LICENSE" 24 | } 25 | ], 26 | "scripts": { 27 | "test": "make test" 28 | }, 29 | "engines": { 30 | "node": ">0.8" 31 | }, 32 | "dependencies": { 33 | "libxmljs": "^0.19.1" 34 | }, 35 | "devDependencies": { 36 | "coffee-script": "1" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lib/js2xml.coffee: -------------------------------------------------------------------------------- 1 | libxml = require "libxmljs" 2 | 3 | class exports.Js2Xml 4 | constructor: ( root_element_name, struct, xml_version="1.0", encoding="UTF-8" ) -> 5 | @doc = libxml.Document xml_version, encoding 6 | root = @doc.node root_element_name 7 | 8 | @convert struct, root, root_element_name 9 | 10 | pluralisation: ( name ) -> 11 | return "item" 12 | 13 | convert: ( structure, document, name ) -> 14 | # String 15 | if typeof structure in [ "string", "number", "boolean" ] 16 | document.text structure.toString() 17 | 18 | # Array 19 | else if typeof structure is "object" and Array.isArray structure 20 | for item in structure 21 | @convert item, document.node( @pluralisation( name ) ), name 22 | 23 | # Generic object 24 | else if typeof structure is "object" 25 | for name, value of structure 26 | @convert value, document.node( name ), name 27 | 28 | return @ 29 | 30 | toString: -> 31 | @doc.toString() 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 Philip Jackson 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /lib/js2xml.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.12.3 2 | var libxml; 3 | 4 | libxml = require("libxmljs"); 5 | 6 | exports.Js2Xml = (function() { 7 | function Js2Xml(root_element_name, struct, xml_version, encoding) { 8 | var root; 9 | if (xml_version == null) { 10 | xml_version = "1.0"; 11 | } 12 | if (encoding == null) { 13 | encoding = "UTF-8"; 14 | } 15 | this.doc = libxml.Document(xml_version, encoding); 16 | root = this.doc.node(root_element_name); 17 | this.convert(struct, root, root_element_name); 18 | } 19 | 20 | Js2Xml.prototype.pluralisation = function(name) { 21 | return "item"; 22 | }; 23 | 24 | Js2Xml.prototype.convert = function(structure, document, name) { 25 | var i, item, len, ref, value; 26 | if ((ref = typeof structure) === "string" || ref === "number" || ref === "boolean") { 27 | document.text(structure.toString()); 28 | } else if (typeof structure === "object" && Array.isArray(structure)) { 29 | for (i = 0, len = structure.length; i < len; i++) { 30 | item = structure[i]; 31 | this.convert(item, document.node(this.pluralisation(name)), name); 32 | } 33 | } else if (typeof structure === "object") { 34 | for (name in structure) { 35 | value = structure[name]; 36 | this.convert(value, document.node(name), name); 37 | } 38 | } 39 | return this; 40 | }; 41 | 42 | Js2Xml.prototype.toString = function() { 43 | return this.doc.toString(); 44 | }; 45 | 46 | return Js2Xml; 47 | 48 | })(); 49 | -------------------------------------------------------------------------------- /test/js2xml_test.coffee: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env coffee 2 | 3 | libxml = require "libxmljs" 4 | 5 | { Js2Xml } = require "../lib/js2xml" 6 | assert = require "assert" 7 | 8 | person = 9 | name: "Phil Jackson" 10 | mood: "Bored" 11 | stuff: [ "xml", "murderers", 2, 2.3, { one: { two: "three" } } ] 12 | morestuff: 13 | milkshake: "banana" 14 | bored: true 15 | 16 | assert.ok js2xml = new Js2Xml "person", person 17 | assert.ok output = js2xml.toString() 18 | 19 | doc = libxml.parseXmlString output 20 | assert.ok doc 21 | 22 | assert.ok doc.get "/person" 23 | assert.ok doc.get "/person/name[text()='Phil Jackson']" 24 | assert.ok doc.get "/person/mood[text()='Bored']" 25 | 26 | for dislike in [ "xml", "murderers", "2", "2.3" ] 27 | assert.ok doc.get "/person/stuff/item[text()='#{dislike}']" 28 | 29 | assert.ok doc.get "/person/stuff/item/one/two[text()='three']" 30 | 31 | assert.ok doc.get "/person/morestuff/milkshake[text()='banana']" 32 | assert.ok doc.get "/person/morestuff/bored[text()='true']" 33 | 34 | # check overriding pluralisation works 35 | 36 | class AppleXml extends Js2Xml 37 | @map = 38 | "apples": "apple" 39 | 40 | pluralisation: ( name ) -> 41 | return @constructor.map[ name ] or "item" 42 | 43 | fruit = 44 | apples: [ "Granny Smith", "Adam's", "Ambrosia" ] 45 | 46 | assert.ok js2xml = new AppleXml "fruit", fruit 47 | assert.ok output = js2xml.toString() 48 | 49 | doc = libxml.parseXmlString output 50 | assert.ok doc 51 | 52 | assert.ok doc.get '/fruit/apples/apple[text()="Ambrosia"]' 53 | 54 | console.log( "All passed." ) 55 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # About 2 | 3 | A very simple library that converts a simple data structure into 4 | XML. Doesn't support namespaces or attributes, just very simple 5 | output. This allows you to write JSON and XML from the same structure 6 | without a middle-man. 7 | 8 | It's written in Coffeescript but the JS is included. 9 | 10 | # Installing 11 | 12 | $ npm install js2xml 13 | 14 | # Usage 15 | 16 | var Js2Xml = require("js2xml").Js2Xml; 17 | 18 | var person = { 19 | name: "Phil Jackson", 20 | mood: "Bored", 21 | stuff: [ "love, "puppies", 2, 2.3, { one: { two: "three" } } ], 22 | morestuff: { milkshake: "banana" } 23 | }; 24 | 25 | var js2xml = new Js2Xml("person", person); 26 | js2xml.toString(); 27 | 28 | Gives: 29 | 30 | 31 | 32 | Phil Jackson 33 | Bored 34 | 35 | love 36 | puppies 37 | 2 38 | 2.3 39 | 40 | 41 | three 42 | 43 | 44 | 45 | 46 | banana 47 | 48 | 49 | 50 | # Pluralisation of lists 51 | 52 | Here's how you might override the pluralisation function to deal with 53 | anonymous list items in Coffeescript: 54 | 55 | class AppleXml extends Js2Xml 56 | @map = 57 | "apples": "apple" 58 | 59 | pluralisation: ( name ) -> 60 | return @constructor.map[ name ] or "item" 61 | --------------------------------------------------------------------------------