Skip to content
Browse files

initial commit

  • Loading branch information...
0 parents commit d80fb0541a93b52a3c1fa74eb7e4a2adc1b6ec47 @c4milo c4milo committed Jun 30, 2011
Showing with 164 additions and 0 deletions.
  1. +2 −0 .gitignore
  2. 0 README.md
  3. +1 −0 index.js
  4. +81 −0 lib/index.js
  5. +16 −0 package.json
  6. +1 −0 test/fixtures/domain.json
  7. +30 −0 test/fixtures/domain.xml
  8. +33 −0 test/test.js
2 .gitignore
@@ -0,0 +1,2 @@
+node_modules
+*.swp
0 README.md
No changes.
1 index.js
@@ -0,0 +1 @@
+module.exports = require('./lib');
81 lib/index.js
@@ -0,0 +1,81 @@
+var expat = require('node-expat');
+var fs = require('fs');
+var parser = new expat.Parser('UTF-8');
+
+// This object will hold the final result.
+var obj = {};
+var currentParent = obj;
+var ancestors = [];
+
+function startElement(name, attrs) {
+ if (! (name in currentParent)) {
+ currentParent[name] = attrs;
+ } else if (!(currentParent[name] instanceof Array)) {
+ // Put the existing object in an array.
+ var newArray = [currentParent[name]];
+ // Add the new object to the array.
+ newArray.push(attrs);
+ // Point to the new array.
+ currentParent[name] = newArray;
+ } else {
+ // An array already exists, push the attributes on to it.
+ currentParent[name].push(attrs);
+ }
+
+ // Store the current (old) parent.
+ ancestors.push(currentParent);
+
+ // We are now working with this object, so it becomes the current parent.
+ if (currentParent[name] instanceof Array) {
+ // If it is an array, get the last element of the array.
+ currentParent = currentParent[name][currentParent[name].length - 1];
+ } else {
+ // Otherwise, use the object itself.
+ currentParent = currentParent[name];
+ }
+}
+
+function charData(data) {
+ data = data.trim();
+ if (!data.length) {
+ return;
+ }
+ currentParent['$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 ((Object.keys(currentParent).length == 1) && ('$t' in currentParent)) {
+ if (ancestor[name] instanceof Array) {
+ //console.log("list-replacing $t in " + name);
+ ancestor[name].push(ancestor[name].pop()['$t']);
+ } else {
+ //console.log("replacing $t in " + name);
+ ancestor[name] = currentParent['$t'];
+ }
+ } else {
+ //console.log("final " + name + ":");
+ //console.log(currentParent);
+ }
+
+ currentParent = ancestor;
+}
+
+parser.on('startElement', startElement);
+parser.on('text', charData);
+parser.on('endElement', endElement);
+
+module.exports.toJson = function(xml, _object) {
+ _object = _object || false;
+ if(parser.parse(xml)) {
+ if(_object) {
+ return obj;
+ }
+ return JSON.stringify(obj);
+ }
+};
+
+
16 package.json
@@ -0,0 +1,16 @@
+{ "name" : "xml2json",
+ "version": "0.1.0",
+ "author": "Andrew Turley",
+ "email": "aturley@buglabs.net",
+ "description" : "Converts xml to json using node-expat.",
+ "repository": "git://github.com/buglabs/node-xml2json.git",
+ "main": "index",
+ "maintainers":[ {
+ "name": "Camilo Aguilar",
+ "email": "camilo@buglabs.net"}
+ ],
+ "dependencies": {
+ "node-expat": "1.3.2"
+ }
+}
+
1 test/fixtures/domain.json
@@ -0,0 +1 @@
+{"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"]}}
30 test/fixtures/domain.xml
@@ -0,0 +1,30 @@
+<domain type='qemu'>
+ <name>QEmu-fedora-i686</name>
+ <uuid>c7a5fdbd-cdaf-9455-926a-d65c16db1809</uuid>
+ <memory>219200</memory>
+ <currentMemory>219200</currentMemory>
+ <vcpu>2</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='cdrom'/>
+ </os>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <disk type='file' device='cdrom'>
+ <source file='/home/user/boot.iso'/>
+ <target dev='hdc'/>
+ <readonly/>
+ </disk>
+ <disk type='file' device='disk'>
+ <source file='/home/user/fedora.img'/>
+ <target dev='hda'/>
+ </disk>
+ <interface type='network'>
+ <source network='default'/>
+ </interface>
+ <graphics type='vnc' port='-1'/>
+ </devices>
+ <ah type='rare' foo='bar'>cosa1</ah>
+ <ah type='normal'>cosa2</ah>
+ <ah>cosa3</ah>
+</domain>
33 test/test.js
@@ -0,0 +1,33 @@
+var 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);
+
+ var jsonFile = basename + '.json'
+ var expected = fs.readFileSync(fixturesPath + '/' + jsonFile) + '';
+
+ if(result) {
+ result = result.trim();
+ }
+
+ if(expected) {
+ expected = expected.trim();
+ }
+
+ assert.deepEqual(result, expected, jsonFile + ' and ' + file + ' are different');
+ }
+ }
+});

0 comments on commit d80fb05

Please sign in to comment.
Something went wrong with that request. Please try again.