Loading XML file into NodeJS as a JSON - javascript

I'm trying to load an XML file into my nodeJS project as a JSON and having some issued. The console.log(JSON.stringify(obj)) returns an undefined value.
var returnJSONResults = function(baseName, queryName) {
var XMLPath = "SomeFile.xml";
var rawJSON = loadXMLDoc(XMLPath);
function loadXMLDoc(filePath) {
var fs = require('fs');
var xml2js = require('xml2js');
var json;
try {
var fileData = fs.readFileSync(filePath, 'ascii');
var parser = new xml2js.Parser();
parser.parseString(fileData.substring(0, fileData.length), function (err, result) {
json = JSON.stringify(result);
console.log(JSON.stringify(result));
});
console.log("File '" + filePath + "/ was successfully read.\n");
return json;
} catch (ex) {...}
}
}();
I'm not sure what I'm doing wrong here but it is either unable to read the file (but doesn't return an error) or does't know how to stringify it.
Thnx.
UPDATE:
changed the parser.parseString and it is working now.
fs.readFile(__dirname + '/'+ filePath, function(err, data) {
parser.parseString(data, function (err, result) {
console.log(result);
console.log('XML converted to JSON');
tempJSON = result;
});
});

Take a look at the following runnable...
Copied your code. not many changes....
It works...
I suspect your XML has something wrong in it.... I created a simple valid XML...
If you add your XML there we can go further to see what's wrong.
Hope that helps.
Runnable link: Runnable Link Here
Shahar.

It seems in your code you doesn't have any variable "obj" . Form your code i think
console.log(JSON.stringify(json));
will work.

Related

JavaScript: Appending a post request json string to existing json file

I have a simple express app that takes a post request with some JSON data. I'd like to take that data and append it to an existing json file (If it exists). Key value pairs may be different. My current version pushes an object to an array of objects. Ideally, I'd like to add just another key/value pair:
app.post('/notes', function(req, res){
var body = "";
req.on('data', function(chunk){
body += chunk;
});
req.on('end', function(){
fs.readFile(__dirname + '/data/notes.json', function(err, data){
if (err) throw err;
console.log(body);
var fileObj = JSON.parse(data.toString());
var postObj = JSON.parse(body);
fileObj.notes.push(postObj);
var returnjson = JSON.stringify(fileObj);
fs.writeFile(__dirname + '/data/notes.json', returnjson, function(err){
if (err) throw err;
res.send(returnjson);
});
});
});
});
Example of what might be in notes.json:
{"note": "Dear Diary: The authorities have removed the black pants from the couch"}
This works, but I'm having trouble wrapping my head around appending whatever json comes in the post (Let's assume there is no nested data in this case).
EDIT: Not the same as just appending to a file. Needs to append to an object within a file.
You can simply iterate through the post object with the help of for ... in loop, and add its properties to the file object. Keep in mind that in this case, if property keys are identical, their value will be overwritten. To avoid it you can make a verification with the help of Object.prototype.hasOwnProperty().
app.post('/notes', function(req, res){
var body = "";
req.on('data', function(chunk){
body += chunk;
});
req.on('end', function(){
fs.readFile(__dirname + '/data/notes.json', function(err, data){
if (err) throw err;
console.log(body);
var fileObj = JSON.parse(data.toString());
var postObj = JSON.parse(body);
for(var key in postObj) {
fileObj[key] = postObj[key];
}
var returnjson = JSON.stringify(fileObj);
fs.writeFile(__dirname + '/data/notes.json', returnjson, function(err){
if (err) throw err;
res.send(returnjson);
});
});
});
});
Here is for ... each statement, if you don't want to overwrite properties. New properties would be generated with suffixes like: _1, _2 etc. You can also use something like shortid to be sure that properties do not repeat, but it would be more ugly and less readable.
for(var key in postObj) {
if(fileObj.hasOwnProperty(key)) {
while(true) {
i++;
newKey = key + '_' + i;
if(fileObj.hasOwnProperty(newKey) == false) {
fileObj[newKey] = postObj[key];
break;
}
}
} else {
fileObj[key] = postObj[key];
}
}

Convert string which is read from a file to json object in nodejs

I am reading a string from a file and want to convert it into a json object
File content: {name:"sda"}
Code:
var fs=require('fs');
var dir='./folder/';
fs.readdir(dir,function(err,files){
if (err) throw err;
files.forEach(function(file){
fs.readFile(dir+file,'utf-8',function(err,jsonData){
if (err) throw err;
var content=jsonData;
var data=JSON.stringify(content);
console.log(data);
});
});
But I am getting this output: {name:\"sda\"}
Since your file is not a valid JSON, you can use eval (it's a dirty hack but it works), example :
data = '{name:"sda"}';
eval('foo = ' + data);
console.log(foo);
In addition to JSON.stringify() method which converts a JavaScript value to a JSON string, you can also use JSON.parse() method which parses a string as JSON:
fs.readFile(dir+file,'utf-8',function(err, jsonData){
if (err) throw err;
var content = JSON.stringify(jsonData);
console.log(content);
var data = JSON.parse(content);
console.log(data);
});
Check the demo below.
var jsonData = '{name:"sda"}',
content = JSON.stringify(jsonData),
data = JSON.parse(content);
pre.innerHTML = JSON.stringify(data, null, 4);
<pre id="pre"></pre>

Get array data from angularjs

First of all, sorry for my English. I'm wondering how to get an array data from angularjs, so i can save it with nodejs.
Here is my angularjs script:
angular.module('myAddList', [])
.controller('myAddListController', function(){
var addList = this;
addList.lists = [];
addList.tambah = function(){
addList.lists.push({title:addList.listTitle,greet:addList.listGreet});
addList.listTitle = '', addList.listGreet = '';
}
addList.hapusList = function(list){
addList.lists.splice(addList.lists.indexOf(list), 1);
}
});
and here is my nodejs:
var fs = require("fs");
var d = new Date();
var myJson = {title : {
"lists": []
}
};
function saveFile(){
fs.writeFile( document.getElementById("namafile").value + ".json", JSON.stringify( myJson ), "utf8", function(err) {
if(err) {
return console.log(err);
}else if(!err){
console.log("The file was saved!");
}
});
}
I think "myJson" should be from angularjs array which is "addList.lists = [];" but i dont know how to do that. Or maybe there is an alternative way?
-- Edit --
I think the only solution is to save the array to localStorage and save it to json format. But i have another problem it replace all whitespaces to this character "\" it so annoying.
Here is the following code (add a few changes), let's assume we already stored array to localStorage and save it using nodejs:
var fs = require("fs");
var myJson = {
key: "myvalue"
};
var d = new Date();
var locS = localStorage.getItem("invoice");
function saveFile(){
var nama = document.getElementById("namaFile").value;
fs.writeFile( nama + ".json", JSON.stringify( locS ), "utf8", function(err) {
if(err) {
return console.log(err);
}else if(!err){
console.log("The file was saved!");
}
});
}
myJson = fs.readFile("undefined.json", "utf8", function (err,data) {
if (err) {
return console.log(err);
}
console.log(JSON.parse(data));
console.log(data[2]);});
if i run this code, it give me a nice output
console.log(JSON.parse(data));
and when i tried this
console.log(data[2]);
it give me "\" as an output, btw here is the json file
"{\"tax\":13,\"invoice_number\":10,\"customer_info\":{\"name\":\"Mr. John Doe\",\"web_link\":\"John Doe Designs Inc.\",\"address1\":\"1 Infinite Loop\",\"address2\":\"Cupertino, California, US\",\"postal\":\"90210\"},\"company_info\":{\"name\":\"Metaware Labs\",\"web_link\":\"www.metawarelabs.com\",\"address1\":\"123 Yonge Street\",\"address2\":\"Toronto, ON, Canada\",\"postal\":\"M5S 1B6\"},\"items\":[{\"qty\":10,\"description\":\"Gadget\",\"cost\":9.95,\"$$hashKey\":\"004\"}]}"
Make $http request to your nodejs server like that
angular.module('myAddList', [])
.controller('myAddListController', function($http){//inject $http
var addList = this;
addList.lists = [];
addList.tambah = function(){
addList.lists.push({title:addList.listTitle,greet:addList.listGreet});
addList.listTitle = '', addList.listGreet = '';
}
addList.hapusList = function(list){
addList.lists.splice(addList.lists.indexOf(list), 1);
}
$http.post('your server url',addList).success(function(successReponse){
//do stuff with response
}, function(errorResponse){
//do stuff with error repsonse
}
});
and then you must have route for that request with post type, and then in controller that performs this route request you must perform your file save operations

Sending a file and some string value in single post request using angular controller

I am trying to upload an image to the server along with that I am sending a string value through $ upload post method. Some how I am able to process the requested file through the $upload method. I dont know how to access the string data that I send through this post request.Here is my controller code
$scope.string1="abcd";
createFile = $scope.files.slice(0);
console.log(createFile);
console.log("upload function");
if (createFile) { // console.log(file.name);
$scope.upload = $upload.upload({
url: '/uploadResortsImage', //upload.php script, node.js route, or servlet url
method: 'POST',
data: {
myObj: $scope.myModelObj,
$scope.dataone:$scope.string1,
},
file: createFile, // or list of files ($files) for html5 only
// fileName: this.name +'.pdf', //or ['1.jpg', '2.jpg', ...] // to modify the name of the file(s)
})
My appliaction stack is meanjs and Here goes my server code.
exports.upload = function (req, res) {
console.log("upload function");
console.log(req);
var filename = '',
target_path = '';
console.log(req.files);
var form = new formidable.IncomingForm();
form.parse(req, function (err, fields, files) {
console.log(files.file);
var tmp_path = files.file.path;
var tmp_path_string = String(tmp_path);
console.log(tmp_path_string);
filename = files.file.name;
var dir = "./public/uploads";
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir);
}
var dir1 = dir + '/' + resortid;
if (!fs.existsSync(dir1)) {
fs.mkdirSync(dir1);
}
var dest_path = dir1 + "/";
target_path = dest_path + filename;
console.log(dest_path);
console.log(filename);
console.log(target_path);
var target_path_string = String(target_path);
fs.rename(tmp_path_string, target_path_string, function (err) {
if (err) {
throw err;
console.log("fail");
console.log(err);
} else {
console.log("successful");
done(err, resort);
}
});
});
}
I think this what you need
data: {
myObj: $scope.myModelObj,
myObjB: $scope.string1,
},
Then on the server side, you would just access that myObjB property or whatever you decide to call it in the incoming form values collection depending on what your are using server side. Using $scope.dataone as a property name in your data object doesn't make sense as that's a scope property from elsewhere in your AngularJS code, stick to simple property names.
I was using formidabble plug in the node application.My code goes like this and I am able to access the send data objects in the server side.
form.parse(req, function (err, fields, files) {
var data_received= fields.myObjB;
}
Thanks.

xml2js read from url

So I have NodeJS and installed the module xml2js. In the tutorial we have an example taking an xml file from directory and convert it with JSON.stringify() as in the example. Now is there a possibility instead of calling the local xml file (foo.xml), to call a url of XML service for ex: www.wunderground.com/city.ect/$data=xml
var parser = new xml2js.Parser();
parser.addListener('end', function(result) {
var res = JSON.stringify(result);
console.log('converted');
});
fs.readFile(__dirname + '/foo.xml', function(err, data) {
parser.parseString(data);
});
You need to create an http request instead of reading a file. Something like this, I think:
http.get("http://www.google.com/index.html", function(res) {
res.on('data', function (chunk) {
parser.parseString(chunk);
});
}).on('error', function(e) {
console.log("Got error: " + e.message);
});
http://nodejs.org/api/http.html#http_http_request_options_callback

Categories