.gitignore000066400000000000000000000000231516074607400130530ustar00rootroot00000000000000node_modules *.swp .npmignore000066400000000000000000000000151516074607400130630ustar00rootroot00000000000000node_modules README.md000066400000000000000000000012621516074607400123500ustar00rootroot00000000000000# 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.js000066400000000000000000000000431516074607400125320ustar00rootroot00000000000000module.exports = require('./lib'); lib/000077500000000000000000000000001516074607400116365ustar00rootroot00000000000000lib/index.js000066400000000000000000000001561516074607400133050ustar00rootroot00000000000000var exports = module.exports; exports.toJson = require('./xml2json'); exports.toXml = require('./json2xml'); lib/json2xml.js000066400000000000000000000023421516074607400137510ustar00rootroot00000000000000module.exports = function toXml(json, xml) { var xml = xml || ''; if (json instanceof Buffer) { 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.js000066400000000000000000000061111516074607400137470ustar00rootroot00000000000000var expat = require('node-expat'); var fs = require('fs'); // This object will hold the final result. var obj = {}; var currentObject = {}; var ancestors = []; var options = {}; //configuration options function startElement(name, attrs) { if(options.coerce) { // Looping here in stead of making coerce generic as object walk is unnecessary for (var key in attrs) { if (attrs.hasOwnProperty(key)) { attrs[key] = coerce(attrs[key]); } } } if (! (name in currentObject)) { currentObject[name] = attrs; } else if (! (currentObject[name] instanceof Array)) { // 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 (currentObject[name] instanceof Array) { // 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'] = coerce((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 (ancestor[name] instanceof Array) { ancestor[name].push(ancestor[name].pop()['$t']); } else { ancestor[name] = currentObject['$t']; } } } currentObject = ancestor; } function coerce(val) { if (!options.coerce) { return val; } var num = Number(val); if (!isNaN(num)) { return num; } switch (val.toLowerCase()){ case 'true': case 'yes': return true; case 'false': case 'no': return false; default: return val; } } 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 }; for (var opt in _options) { options[opt] = _options[opt]; } if (!parser.parse(xml)) { throw new Error('There are errors in your xml file: ' + parser.getError()); } if (options.object) { return obj; } return JSON.stringify(obj); }; package.json000066400000000000000000000006451516074607400133630ustar00rootroot00000000000000{ "name" : "xml2json", "version": "0.2.4", "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"}], "dependencies": { "node-expat": "1.4.1" } } test/000077500000000000000000000000001516074607400120475ustar00rootroot00000000000000test/coerce-overhead.js000066400000000000000000000007671516074607400154520ustar00rootroot00000000000000var fs = require('fs'); var parser = require('../lib'); var file = __dirname + '/fixtures/large.xml'; var data = fs.readFileSync(file); // With coercion var t0 = Date.now(); for(var i = 0; i < 10000; i++) { var result = parser.toJson(data, {reversible: true, coerce: true, object: true}); } console.log(Date.now() - t0); // Without coercion var t0 = Date.now(); for(var i = 0; i < 10000; i++) { result = parser.toJson(data, {reversible: true, object: true}); } console.log(Date.now() - t0); test/fixtures/000077500000000000000000000000001516074607400137205ustar00rootroot00000000000000test/fixtures/coerce.xml000066400000000000000000000011671516074607400157070ustar00rootroot00000000000000 12345 this is a string value 104.95 104.95 0 true 0 2012-02-16T17:03:33.000-07:00 SmDZ8RlMIjDvlEW3KUibzj2Q test/fixtures/domain-reversible.json000066400000000000000000000013411516074607400202210ustar00rootroot00000000000000{"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"}]}} test/fixtures/domain.json000066400000000000000000000012601516074607400160610ustar00rootroot00000000000000{"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"]}} test/fixtures/domain.xml000066400000000000000000000013711516074607400157130ustar00rootroot00000000000000QEmu-fedora-i686c7a5fdbd-cdaf-9455-926a-d65c16db18092192002192002hvm/usr/bin/qemu-system-x86_64cosa1cosa2cosa3 test/fixtures/large.xml000066400000000000000000000763651516074607400155550ustar00rootroot00000000000000 Success 1.1.0 2012-01-20T01:36:25.904Z 3 1.0.0 text/html <a>qds=0.1723&!_dcat_leaf=617,163826,617,163826,15077&pct=94.84&nai=44&nhalf=0&ncbt=0&nmq=2&!SIBE=avatar+blue+ray+3d,JPIA9PMIDQ8:7M&auctions=44&nbi=22&iat=4&trsi=0&prof=5841&nabi=16&fixedprices=4&!ptrid=Pr1062_10,Pr5841_2&pcc=2&nProdSur=2&tcatid=617</a> 118 113 2012-01-19T18:36:02.000-07:00 81996414 Avatar (DVD, 2010) 78 4.0 2012-01-19T21:01:14 13.5 34 3.96 44 http://i.ebayimg.com/22/!!d7WiF!EWM~$(KGrHqMOKikEvOnbKY1gBL9fO1lupQ~~_6.JPG?set_id=89040003C1 82093597 Avatar (Blu-ray/DVD, 2010, 2-Disc Set) 74 15.01 2012-01-19T19:12:15 20.0 26 11.96 48 http://i.ebayimg.com/01/!!d8dfeQ!mM~$(KGrHqUOKjcEwhzOMI3VBMSIdcD!Yw~~_6.JPG?set_id=89040003C1 220931734658 AVATAR 3D BLU-RAY FACTORY SEALED -new,sealed- 70.99 79.99 1 300 2012-01-19T19:15:14.000-07:00 Sm86FNl5NfYQDIhtWAUiWbqQ 170763800829 Avatar 3D Blu-ray Disc - BRAND NEW - FACTORY SEALED - PANASONIC EXCLUSIVE 61.0 74.99 4 300 0 2012-01-19T19:51:57.000-07:00 SmJODPpMeeyd8FcfsNsrdYWA 220931945435 New Sealed James Cameron's AVATAR 3D Blu-Ray Panasonic Exclusive PG-13 DVD RARE 61.0 0.0 14 300 2012-01-19T21:19:51.000-07:00 Sm4H_Y9vXU4EKx-f3wk3EF7A 320829372998 NEW & SEALED 3D Blu-ray Panasonic Exclusive "AVATAR" FAST FREE SHIPPING! 89.99 98.99 0 0 399 2012-01-19T21:53:36.000-07:00 SmcgSHPYl8Y2gPS8cJN-OcrA 190628955236 NEW *Rare* AVATAR Blu-ray 3D Panasonic Exclusive *NOT SOLD IN STORES* 99.99 109.99 0 0 2012-01-20T06:10:25.000-07:00 Sm2CvUgNznvK-l0t-rZ3n4GQ 160718400852 Avatar 3D Blu-Ray Panasonic Exclusive __ Unopened - Original factory shrink wrap 55.01 75.0 8 300 2012-01-20T10:48:32.000-07:00 SmiTg55gmYOWAJ1XbSQ98ECA 130632208352 Avatar 3D Blu-Ray - Panasonic Exclusive (brand new, factory sealed) 62.85 94.99 12 300 2012-01-20T13:52:56.000-07:00 SmtrdC17WyVHvvn_ZgWTXgiA 230733466588 Brand new Avatar 3d blu ray disc. Factory sealed (panasonic exclusive) 50.0 0.0 4 300 2012-01-20T13:53:56.000-07:00 SmlZdHT_kLO9ggmFSsxS0QCA 320829809050 Avatar 3D Blu-ray Panasonic Exclusive Sealed NEW 60.0 0.0 0 0 2012-01-20T14:31:02.000-07:00 SmUBlLP2lRLEf0VBWm8ilplg 130630659754 AVATAR 3D Blu-ray Brand New Factory Sealed (Original Panasonic Exclusive) 58.0 0.0 15 300 2012-01-20T14:34:31.000-07:00 Sm2MdiMGiOAE-0Qh8yDBew4g 150734718107 Avatar 3D Blu-ray Brand New Factory Sealed Panasonic Exclusive 104.99 104.99 9 0 325 1690 -2147481648 16777216 2012-02-09T17:00:38.000-07:00 SmVD9hFn5o8UG2kBlJRLDI4A 260937482985 BRAND NEW Avatar 3D Blu-Ray DVD - Sealed 70.0 0.0 0 0 0 2012-01-20T20:25:55.000-07:00 Smn_b9xfCFZUjdMMzg6b5U_w 120843131441 Avatar 3D blu ray disc factory sealed NIB 3 d version 51.0 0.0 3 0 2012-01-20T20:30:19.000-07:00 SmRNvQVngyrAAzzicicxqF-g 330673600191 AVATAR 3D Blu Ray-Factory Sealed..FREE Shipping!!! 49.95 0.0 1 0 2012-01-20T21:51:58.000-07:00 SmuX1a85zuIEuO2Jv-BJzp0A 200700624127 AVATAR, 3D, BLU RAY, BRAND NEW AND FACTORY SEALED 50.0 0.0 1 300 2012-01-20T23:22:51.000-07:00 SmPCqKpN0DBoNqaMNhr3vO9Q 130632758842 3D Avatar Blue Ray Disk 75.0 90.0 0 300 0 2012-01-21T15:27:37.000-07:00 Smff4598BYjt0QU3hnozg9qQ 180798514647 Avatar Blu-ray 3D Panasonic Exclusive - Sealed NEW 32.93 0.0 18 300 1000 2012-01-21T15:43:43.000-07:00 Smt8taWyWmsG_Tw-zHfZUmHA 380401406666 AVATAR 3D BLU-RAY MOVIE NEW EDITION --FACTORY SEALED ! 95.0 95.0 11 0 2012-02-09T08:43:23.000-07:00 SmipHloK8dVCLobrpiHi9soA 120845197426 Avatar 3D Blu Ray Exlusive Factory Sealed Brand New 70.0 100.0 1 0 2012-01-22T05:35:49.000-07:00 SmSjLcuOvW6zhwC5Lx1h5S-g 320830894431 AVATAR BLU-RAY 3D MOVIE; BRAND NEW, FACTORY SEALED 75.0 0.0 0 0 2012-01-22T15:55:06.000-07:00 SmE7UPFuIq9m6x9xjY7QFbXg 330672702076 AVATAR 3D BLU-RAY 3D - Brand New Unopened 60.0 100.0 1 300 2012-01-22T16:25:14.000-07:00 SmN_U5mt-bejXAlAg-oekhYg 220933768045 Blue-ray 3D Avatar DVD, Brand New in Original Packaging, Never opened 39.0 0.0 8 0 2012-01-22T16:58:20.000-07:00 SmZGHJZ-gikK2yYeIDhWxFvQ 170766321061 Avatar 3D blu ray, exclusive Panasonic release. New sealed in hand. Great 3 D 43.99 85.0 6 300 2012-01-22T17:26:33.000-07:00 SmnvAaEh-waB7BW4_CKGWdBQ 300651900316 AVATAR BLU-RAY 3D"" PANASONIC EXCLUSIVE NEW SEALED not found in stores 31.0 0.0 8 300 2012-01-22T18:55:21.000-07:00 SmntGH04Op5W7KLFnYdvAeZA 180798015096 Avatar 3D Blu-ray Panasonic Exclusive, factory sealed, minor box defect. 49.0 0.0 0 0 2012-01-22T19:53:02.000-07:00 SmeZSdGGu_jOcIPVFQpAVQFA 160717564858 Avatar 3D SEALED Blu-ray Panasonic Exclusive 31.0 0.0 12 0 2012-01-22T20:07:34.000-07:00 SmiWNF8nl9ntob9GViXnyBBA 220932049647 AVATAR 3D BLU-RAY~BRAND NEW~FACTORY SEALED IN SHRINK~PANASONIC PROMO EXCLUSIVE!! 109.99 120.99 0 300 2012-01-22T23:01:04.000-07:00 SmBH2AwKhfOLm0BP7eXlEhNA 180800257998 Avatar Blu-Ray 3D Limited Release Promo Disc - Factory Sealed 89.0 89.0 0 0 2012-01-26T10:27:27.000-07:00 Sm0gVHFWw_MaLbyOMYjwaiog 120844739120 Avatar 3D Blu Ray Factory Sealed Incl. Two 3D Glasses !! 79.0 0.0 13 0 -2147481148 268435456 2012-01-23T09:38:20.000-07:00 SmbzRQ-rZ_MKXYvTkoispOVw 140683495269 New AVATAR Blu-ray 3D Panasonic Exclusive *NOT SOLD IN STORES* 32.91 99.0 2 0 2012-01-23T15:02:11.000-07:00 SmZ4iQNLIAiTz0o_0j3bIW9w 170765774879 Avatar 3D Blu-ray Panasonic Exclusive - Not available in stores! 31.93 0.0 20 0 2012-01-23T15:13:47.000-07:00 SmbSQ1lnQYPcCfvpfpvToS8A 180798565141 Avatar 3D Blu-Ray - BRAND NEW and SEALED - Panasonic Exclusive 3 D BluRay 33.93 0.0 11 0 2012-01-23T17:47:14.000-07:00 SmvZYYqQS_evOSt3pDfMno8Q 110810440275 AVATAR 3D Blu-ray Brand New Factory Sealed ñ FREE SHIPPING! 58.99 0.0 22 0 2012-01-23T17:57:52.000-07:00 SmBi99v66zqHKYkKvIAJ9pQA 190628845216 AVATAR 3D Blu-Ray - Panasonic Exclusive - FACTORY SEALED - Free Shipping 31.0 0.0 6 0 2012-01-23T19:51:19.000-07:00 SmE2rnqwwG4Ox7y9QPAZwmDA 320831486088 Avatar 3D Blu-Ray NEW Factory Sealed - Panasonic Exclusive - FREE SHIPPING 50.0 0.0 2 0 2012-01-23T21:10:17.000-07:00 Smp2gxOJCJH8Wm7P4n6akm1Q 260937208793 3D Avatar 3D Blu-ray 3D bluray 3D blu ray Brand new sealed NIB new in box 90.0 120.0 0 300 200 500 2012-01-24T09:58:40.000-07:00 SmKwKZry-47DifBrUXtAjLIA 290659864842 Avatar 3D Blu Ray Panasonic Exclusive Sealed Promo DTS-HD 5.1 Master 26.0 0.0 7 0 -2147483148 2 2012-01-24T11:52:45.000-07:00 Smc5ACn355MwQ36-8qVhYJMA 120845375724 Avatar Blu-Ray 3D Panasonic Exclusive Movie Brand New Sealed 80.0 0.0 0 300 2012-01-24T12:15:28.000-07:00 SmTRKrb5snFcN629amftoz5g 170766323196 Avatar 3D Blu-ray Brand New Factory Sealed 26.0 0.0 8 0 2012-01-24T17:32:24.000-07:00 Smeip7wxKlFhh3GztuS7jkiA 220936324950 AVATAR 3D BLU-RAY~BRAND NEW~FACTORY SEALED IN SHRINK~PANASONIC PROMO EXCLUSIVE!! 89.99 99.99 0 300 2012-01-24T18:15:10.000-07:00 Sm_JHQtAx3TZEDGP0Lw6ObpA 320831969924 AVATAR 3D Blu Ray (Original Panasonic Exclusive) - Like NEW 40.0 86.0 1 300 2012-01-24T20:26:55.000-07:00 Smnzp3FhNin5GcqoftqekADg 150738091689 New RARE Avatar Blu-ray Blu Ray 3-D 3 D Panasonic Exclusive NOT SOLD IN STORES 199.99 199.99 0 0 -2147482303 268435456 -2147480098 268435456 2012-01-22T16:26:56.000-07:00 SmuB9oGX7_insOHm5Wm1mtPA 200697624093 New Avatar 3D Blu-Ray Panasonic Exclusive Factory Sealed New 105.0 105.0 1 0 0 2012-02-06T13:17:53.000-07:00 Sm4Ih4QKzC5nfe3TenzzSiSA 320832354417 Avatar 3-d Blu Ray With Sony Blu Ray Player 150.0 0.0 0 300 2012-01-25T12:33:27.000-07:00 SmQ-meY-Gw-I--dGgWe4aNdA 320832387656 James Cameron's AVATAR Exclusive Blu-Ray 3D **FACTORY SEALED** 85.0 0.0 0 0 2012-01-25T13:20:30.000-07:00 Sm-_Y6j0vHctWYksalN84VFw 320832469688 Avatar Blu-ray 3D 39.99 0.0 0 241 2012-01-25T16:09:30.000-07:00 Sme85gcM76LwgS-iccLJrT7g 110811394468 NEW- AVATAR 3D Blu-Ray Movie- PANASONIC EXCLUSIVE & FACTORY SEALED!! 31.0 95.0 3 0 2012-01-25T20:47:13.000-07:00 Sml7KjYSTL-Pw446Zcx9UrNw 190629134325 AVATAR 3D BLU-RAY DISC Panasonic Exclusive, Factory Sealed Dolby Digital DTS-HD 104.95 104.95 0 0 2012-02-16T17:03:33.000-07:00 SmDZ8RlMIjDvlEW3KUibzj2Q US_DVD_HD_DVD_Blu_ray 108.0 100.0 90.24579692259518 157204 test/test-coerce.js000066400000000000000000000016571516074607400146330ustar00rootroot00000000000000var fs = require('fs'); var parser = require('../lib'); var assert = require('assert'); var file = __dirname + '/fixtures/coerce.xml'; var data = fs.readFileSync(file); // With coercion var result = parser.toJson(data, {reversible: true, coerce: true, object: true}); assert.strictEqual(result.itemRecord.value[0].longValue['$t'], 12345); assert.strictEqual(result.itemRecord.value[1].stringValue.number, false); assert.strictEqual(result.itemRecord.value[2].moneyValue.number, true); assert.strictEqual(result.itemRecord.value[2].moneyValue['$t'], 104.95); // Without coercion result = parser.toJson(data, {reversible: true, object: true}); assert.strictEqual(result.itemRecord.value[0].longValue['$t'], '12345'); assert.strictEqual(result.itemRecord.value[1].stringValue.number, 'false'); assert.strictEqual(result.itemRecord.value[2].moneyValue.number, 'true'); assert.strictEqual(result.itemRecord.value[2].moneyValue['$t'], '104.95');test/test.js000066400000000000000000000034301516074607400133640ustar00rootroot00000000000000var fs = require('fs'); var path = require('path'); var parser = require('../lib'); var assert = require('assert'); var fixturesPath = './fixtures'; fs.readdir(fixturesPath, function(err, files) { for (var i in files) { var file = files[i]; var ext = path.extname(file); if (ext == '.xml') { var basename = path.basename(file, '.xml'); var data = fs.readFileSync(fixturesPath + '/' + file); var result = parser.toJson(data, {reversible: true}); var data2 = fs.readFileSync(fixturesPath + '/' + file); result = parser.toJson(data2); var jsonFile = basename + '.json'; var expected = fs.readFileSync(fixturesPath + '/' + jsonFile) + ''; if (expected) { expected = expected.trim(); } assert.deepEqual(result, expected, jsonFile + ' and ' + file + ' are different'); console.log('[xml2json: ' + file + '->' + jsonFile + '] passed!'); } else if( ext == '.json') { var basename = path.basename(file, '.json'); if (basename.match('reversible')) { var data = fs.readFileSync(fixturesPath + '/' + file); var result = parser.toXml(data); var xmlFile = basename.split('-')[0] + '.xml'; var expected = fs.readFileSync(fixturesPath + '/' + xmlFile) + ''; if (expected) { expected = expected.trim(); } //console.log(result + '<---'); assert.deepEqual(result, expected, xmlFile + ' and ' + file + ' are different'); console.log('[json2xml: ' + file + '->' + xmlFile + '] passed!'); } } } });