xml2js read from url - javascript

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

Related

Get all files in directory json

I want get all files json in my directory for search into it.
$('#get-data').click(function () {
var showData = $('#show-data');
$.getJSON('/data/**all files json**', function (data) {
console.log(data);
var items = data.items.map(function (item) {
return item.key + ': ' + item.value;
});
showData.empty();
if (items.length) {
var content = '<li>' + items.join('</li><li>') + '</li>';
var list = $('<ul />').html(content);
showData.append(list);
}
});
showData.html(data);
});
Do you think its possible or i need use other method ?
Thx
You cannot make a wildcard AJAX request that will return all the possible JSON files on your server. You need to know in advance the exact endpoint that you will be sending your request to. Otherwise it would be a security vulnerability if all clients could know in advance what files are available on the server.
So one possible strategy here would be to have some /describe endpoint on your server which will return a list of all available JSON files. Then the client will first make an AJAX request to this endpoint and then for each returned endpoint in the list it will make a separate AJAX request:
$.getJSON('/data/discover', function (data) {
// suppose that data looks like this:
// ["/data/a.json", "/data/b.json", "/data/c.json"]
for (var i := 0; i < data.length; i++) {
// send an AJAX request to each individual JSON file
// available on the server as returned by the discover endpoint
$.getJSON(data[i], function (result) {
...
});
}
});
Basically you can't request for multiple files by one request.
However the scenario is perfect fit for async.parallel:
var async = require('async');
app.get('/json', function(req, res) {
var work = {
file01: async.apply(fs.readFile, __dirname + '/file01.json'),
file02: async.apply(fs.readFile, __dirname + '/file02.json')
};
async.parallel(work, function (error, results) {
if (error) {
res.status(500).send(error);
return;
}
//might need string->Object here
results['file01'] = JSON.parse(results['file01']);
results['file02'] = JSON.parse(results['file02']);
res.send(results);
});
});

Log images after successful http request using Node.js

I'm creating a script that will make a request 2 times per second to a localserver of cameras network and after it gets a positive response that camera detected someone I want to log three images.
In the json config file I have the triggerURL of the server, the interval port, the dataDir where logged images should be saved and a track array which contains the url of those images and the fileName they should receive.
This is the code of the script I use after reading the JSON file:
var configGet = {
host: config.triggerURL
, port: config.interval
, method: 'GET'
};
setInterval(function () {
var request = http.request(configGet, function (response) {
var content = "";
// Handle data chunks
response.on('data', function (chunk) {
content += chunk;
});
// Once we're done streaming the response, parse it as json.
response.on('end', function () {
var data = JSON.parse(response);
if (data.track.length > 0) {
//log images
var download = function (uri, filename, callback) {
request.head(uri, function (err, res, body) {
request(uri)
.pipe(fs.createWriteStream(filename))
.on('close', callback);
});
};
for (var image in data.track) {
var path = config.dataDir + '/' + image.fileName
download(image.url, path.format(config.timestamp), function () {
console.log('done');
});
}
}
});
// Report errors
request.on('error', function (error) {
console.log("Error while calling endpoint.", error);
});
request.end();
}, 500);
});
I have the following questions:
This method produces some kind of error with the download process of the images.Can you identify it?
Is there a better way of doing this process?
Without running the code or deeper inspection; should not "data = JSON.parse(response)" rather be "data = JSON.parse(content)"? Also, if data is undefined or does not contain "track" the "if (data.track.length > 0)" will throw an error. This can be fixed with "if (data && data.track && data.track.length > 0)".
I can not think of a very much better way. I would break it up more in functions to make the code more clear though.

Perform get request and print xml output in Node.js

New to Node.js (and javascript) i'm trying to make a request to my provider which is supposed to send me back an xml file.
So i have my Node.js file : app.js
In this file i have chosen to perform a get request the native way (well, i think...) :
// Required ... ('fs','url','http'...)
var file_url = 'http://www.myprovider.../test.xml'; // this url will return an xml file.
var download_file_httpget = function(file_url) {
var options = {
host: url.parse(file_url).host,
port: 80,
path: url.parse(file_url).pathname,
method: 'GET'
};
var completeResponse = '';
var file_name = url.parse(file_url).pathname.split('/').pop();
http.get(options, function(res) {
res.setEncoding('utf8');
var decoder = new StringDecoder('utf8');
res.on('data', function(data) {
completeResponse += data;
}).on('end', function() {
console.log(completeResponse.toSring());
});
});
};
download_file_httpget(file_url);
The problem is when i print the results i get something like :
�*�r��Ff8����ij��.�#�F
�������v������#���[
������G+��*u��D:�q"�0�ß���z�g$���rp��r�r�����c#n# ��������QB>�>&K��6��}L��a#��:b�6�$�h\sDV���o�UfX庮�W��J��Qa{��6����ì��R�+��C6.��5��(���}�S x�,#n�-�E��r�*H������h�J!�G�K�������(ê£tCE�K
So i have understood that the completeReponse is a buffer and that i need to 'convert' this binary data but i have no idea how, the results are always the same when i try to parse the completeReponse.toString() with an XML parser.
I just to call the request, get the xml results as string and then write the file somewhere or convert to JSON.
Can someone help ?
Thank you very much.

Loading XML file into NodeJS as a JSON

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.

Sails.js Sending json object returned in https.request to the view

Just learning Sails.js so go easy on me.
I have queried an XML service and successfully jsonified it using xml2js
var req = https.request(options, function(res) {
var xml = '';
res.on('data', function(chunk) {
xml += chunk;
});
res.on('end', function () {
var result = parseString(xml, function (err, result) {
console.log(JSON.stringify(result)); // Position 1
});
return result;
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
req.write(data);
var result = req.end();
console.log('Result: ' + JSON.stringify(result)); // Position 2
res.view({ message : 'hello', result : result });
The view is loading fine, and <%= message %> outputs hello. Great.
Position1 console.log is returning the stringified json object - Great.
Position 2 consile.log is returning Result: true - Not good.
I need to be able to get that json data to my view for parsing. How do I do this?
It looks like you're assuming that calling req.end() will give you the response from the https.request you started above. There are a couple of things wrong with that:
req.end() is used to finish writing to an open request, not to get a response. According to the docs, the return value is unspecified.
The https.request call is asynchronous; even if req.end() worked like you want it to, the response wouldn't have come in by the time you call it.
The solution is to put your response code (i.e. your res.view) inside the handler for the end event that you've already written. I'd also recommend refactoring your code to use different variable names for the remote request / response so that they don't collide with the req and res variables in your controller action. The whole thing would then be something like:
myAction: function (req, res) {
// Not sure how you're setting options, so just an example
var options = {url: 'http://example.com', ...}
var request = https.request(options, function(response) {
var xml = '';
response.on('data', function(chunk) {
xml += chunk;
});
response.on('end', function () {
var result = parseString(xml, function (err, result) {
return res.view({ message : 'hello', result : JSON.stringify(result)});
});
});
});
request.on('error', function(e) {
console.log('problem with request: ' + e.message);
res.serverError(e);
});
}
You might also look into using something like the Request module to simplify your external request; it would save you from having to write event handlers for data and end.
if you want to pass json to some javascript variable:
var clientJsonVar = <%- JSON.stringify(serverSideJson)%>

Categories