.gitignore000066400000000000000000000000411516103736700130520ustar00rootroot00000000000000node_modules *.swp .settings.xml .npmignore000066400000000000000000000000151516103736700130620ustar00rootroot00000000000000node_modules Makefile000066400000000000000000000006661516103736700125370ustar00rootroot00000000000000SPECS = specs/*.js REPORTER = list JSLINT := /usr/local/bin/gjslint FIX_STYLE := /usr/local/bin/fixjsstyle JSLINT_PARAMS := --custom_jsdoc_tags public,static --recurse lib/ --recurse test/ test: @./node_modules/mocha/bin/mocha \ --require should \ --reporter $(REPORTER) \ --ui bdd \ $(SPECS) jslint: $(JSLINT) $(JSLINT_PARAMS) install: npm install fixstyle: $(FIX_STYLE) $(JSLINT_PARAMS) .PHONY: test jslint fixstyle README.md000066400000000000000000000012621516103736700123470ustar00rootroot00000000000000# Simple SAX-based XML2JSON Parser. It does not parse the following elements: * CDATA sections * Processing instructions * XML declarations * Entity declarations * Comments ## Installation `npm install xml2json` ## Usage ```javascript var parser = require('xml2json'); var xml = "bar"; var json = parser.toJson(xml); //returns an string containing the json structure by default console.log(json); ``` * if you want to get the Javascript object then you might want to invoke parser.toJson(xml, {object: true}); * if you want a reversible json to xml then you should use parser.toJson(xml, {reversible: true}); ## License Copyright 2011 BugLabs Inc. All rights reserved. index.js000066400000000000000000000000431516103736700125310ustar00rootroot00000000000000module.exports = require('./lib'); lib/000077500000000000000000000000001516103736700116355ustar00rootroot00000000000000lib/index.js000066400000000000000000000002701516103736700133010ustar00rootroot00000000000000var exports = module.exports; /** *Exports xml2json module. **/ exports.toJson = require('./xml2json'); /** * Exports json2xml module. **/ exports.toXml = require('./json2xml'); lib/json2xml.js000066400000000000000000000027051516103736700137530ustar00rootroot00000000000000/** * Parses json to xml recursively. * @param {String|Buffer} json The JSON string to be parsed. * @param {String} xml The ongoing xml string * being generated from the json parameter. * @return {String} The ongoing xml. **/ module.exports = function toXml(json, xml) { xml = xml || ''; if (Buffer.isBuffer(json)) { json = json.toString(); } var obj = null; if (typeof(json) == 'string') { try { obj = JSON.parse(json); } catch (e) { throw new Error('The JSON structure is invalid'); } } else { obj = json; } var keys = Object.keys(obj); var len = keys.length; for (var i = 0; i < len; i++) { var key = keys[i]; if (Array.isArray(obj[key])) { var elems = obj[key]; var l = elems.length; for (var j = 0; j < l; j++) { xml += '<' + key + '>'; xml = toXml(elems[j], xml); xml += ''; } } else if (typeof(obj[key]) == 'object') { xml += '<' + key + '>'; xml = toXml(obj[key], xml); xml += ''; } else if (typeof(obj[key]) == 'string') { if (key == '$t') { xml += obj[key]; } else { xml = xml.replace(/>$/, ''); xml += ' ' + key + "='" + obj[key] + "'>"; } } } return xml; }; lib/xml2json.js000066400000000000000000000066361516103736700137620ustar00rootroot00000000000000var expat = require('node-expat'); var fs = require('fs'); // This object will hold the final result. var obj = currentObject = {}; var ancestors = []; var options = {}; //configuration options function startElement(name, attrs) { if (! (name in currentObject)) { currentObject[name] = attrs; } else if (!Array.isArray(currentObject[name])) { // Put the existing object in an array. var newArray = [currentObject[name]]; // Add the new object to the array. newArray.push(attrs); // Point to the new array. currentObject[name] = newArray; } else { // An array already exists, push the attributes on to it. currentObject[name].push(attrs); } // Store the current (old) parent. ancestors.push(currentObject); // We are now working with this object, so it becomes the current parent. if (Array.isArray(currentObject[name])) { // If it is an array, get the last element of the array. currentObject = currentObject[name][currentObject[name].length - 1]; } else { // Otherwise, use the object itself. currentObject = currentObject[name]; } } function text(data) { data = data.trim(); if (!data.length) { return; } currentObject['$t'] = (currentObject['$t'] || '') + data; } function endElement(name) { // This should check to make sure that the name we're ending // matches the name we started on. var ancestor = ancestors.pop(); if (!options.reversible) { if ((Object.keys(currentObject).length == 1) && ('$t' in currentObject)) { if (Array.isArray(ancestor[name])) { ancestor[name].push(ancestor[name].pop()['$t']); } else { ancestor[name] = currentObject['$t']; } } } currentObject = ancestor; } /** * Parses xml to json using node-expat. * @param {String|Buffer} xml The xml to be parsed to json. * @param {Object} _options An object with options provided by the user. * The available options are: * - object: If true, the parser returns a Javascript object instead of * a JSON string. * - reversible: If true, the parser generates a reversible JSON, mainly * characterized by the presence of the property $t. * - sanitize_values: If true, the parser escapes any element value in the xml * that matches one of the following characters: * character | escaped * < < * > > * ( ( * ) ) * # # * & & * " " * ' '. * @return {String|Object} A String or an Object with the JSON representation * of the XML. **/ module.exports = function(xml, _options) { var parser = new expat.Parser('UTF-8'); parser.on('startElement', startElement); parser.on('text', text); parser.on('endElement', endElement); obj = currentObject = {}; ancestors = []; options = { object: false, reversible: false, sanitize_values: false }; for (var opt in _options) { options[opt] = _options[opt]; } if (!parser.parse(xml)) { //console.log('-->' + xml + '<--'); throw new Error('There are errors in your xml file: ' + parser.getError()); } if (options.object) { return obj; } return JSON.stringify(obj); }; package.json000066400000000000000000000007671516103736700133670ustar00rootroot00000000000000{ "name" : "xml2json", "version": "0.3.0", "author": "Andrew Turley", "email": "aturley@buglabs.net", "description" : "Converts xml to json and viceverza, using node-expat.", "repository": "git://github.com/buglabs/node-xml2json.git", "main": "index", "contributors":[ {"name": "Camilo Aguilar", "email": "camilo@buglabs.net"}], "devDependencies": { "mocha": "1.0.3", "should": "0.6.3" }, "dependencies": { "node-expat": "1.5.0" } } specs/000077500000000000000000000000001516103736700122045ustar00rootroot00000000000000specs/fixtures/000077500000000000000000000000001516103736700140555ustar00rootroot00000000000000specs/fixtures/domain-reversible.json000066400000000000000000000013411516103736700203560ustar00rootroot00000000000000{"domain":{"type":"qemu","name":{"$t":"QEmu-fedora-i686"},"uuid":{"$t":"c7a5fdbd-cdaf-9455-926a-d65c16db1809"},"memory":{"$t":"219200"},"currentMemory":{"$t":"219200"},"vcpu":{"$t":"2"},"os":{"type":{"arch":"i686","machine":"pc","$t":"hvm"},"boot":{"dev":"cdrom"}},"devices":{"emulator":{"$t":"/usr/bin/qemu-system-x86_64"},"disk":[{"type":"file","device":"cdrom","source":{"file":"/home/user/boot.iso"},"target":{"dev":"hdc"},"readonly":{}},{"type":"file","device":"disk","source":{"file":"/home/user/fedora.img"},"target":{"dev":"hda"}}],"interface":{"type":"network","source":{"network":"default"}},"graphics":{"type":"vnc","port":"-1"}},"ah":[{"type":"rare","foo":"bar","$t":"cosa1"},{"type":"normal","$t":"cosa2"},{"$t":"cosa3"}]}} specs/fixtures/domain.json000066400000000000000000000012601516103736700162160ustar00rootroot00000000000000{"domain":{"type":"qemu","name":"QEmu-fedora-i686","uuid":"c7a5fdbd-cdaf-9455-926a-d65c16db1809","memory":"219200","currentMemory":"219200","vcpu":"2","os":{"type":{"arch":"i686","machine":"pc","$t":"hvm"},"boot":{"dev":"cdrom"}},"devices":{"emulator":"/usr/bin/qemu-system-x86_64","disk":[{"type":"file","device":"cdrom","source":{"file":"/home/user/boot.iso"},"target":{"dev":"hdc"},"readonly":{}},{"type":"file","device":"disk","source":{"file":"/home/user/fedora.img"},"target":{"dev":"hda"}}],"interface":{"type":"network","source":{"network":"default"}},"graphics":{"type":"vnc","port":"-1"}},"ah":[{"type":"rare","foo":"bar","$t":"cosa1"},{"type":"normal","$t":"cosa2"},"cosa3"]}} specs/fixtures/domain.xml000066400000000000000000000013711516103736700160500ustar00rootroot00000000000000QEmu-fedora-i686c7a5fdbd-cdaf-9455-926a-d65c16db18092192002192002hvm/usr/bin/qemu-system-x86_64cosa1cosa2cosa3 specs/spec.js000066400000000000000000000007241516103736700134770ustar00rootroot00000000000000var fs = require('fs'); var path = require('path'); describe('xml2json', function() { it('should convert xml to json'); it('should convert xml to reversible json'); it('should convert xml to a javascript object'); it('should escape problematic characters in element values'); }); describe('json2xml', function() { it('should return -1 when the value is not present'); it('should return the correct index when the value is present'); });