I'm trying to run an empty simple code snippet to test SaxonJS 1.1.0 on NodeJs v8.11.1 on Windows 10.
require('./Saxon-JS-1.1.0/SaxonJS.js');
But I got this error :
PS C:\XXX\sandbox\xsl-transformation> node main.js
C:\XXX\xsl-transformation\Saxon-JS-1.1.0\SaxonJS.js:17136
setPlatform(JSTestDriver.platform);
^
ReferenceError: JSTestDriver is not defined
at initialize (C:\XXX\sandbox\xsl-transformation\Saxon-JS-1.1.0\SaxonJS.js:17136:25)
Looking at the source code, I can see :
function initialize() {
"use strict";
if (inBrowser) {
setPlatform(BrowserPlatform.platform);
saxonPrint("Saxon-JS " + getProcessorInfo().productVersion + " in browser", 0);
} else {
// Currently only Nashorn. (Later need to distinguish from Node case)
// Nashorn JSTestDriver
setPlatform(JSTestDriver.platform);
saxonPrint("Saxon-JS " + getProcessorInfo().productVersion + " in
Nashorn");
// node NodePlatform
}
if (typeof platform.initialize === "function") {
platform.initialize();
}
}
It seems Node Platform is not implemented.
However, in the documentation, it is written :
We're talking here primarily about running Saxon-JS in the browser.
However, it's also capable of running in server-side JavaScript
environments such as Node.js (not yet fully supported in this
release).
I deeply search a code snippet of SaxonJS/NodeJS but I did not find one.
Has anyone a snippet code of SaxonJS working on NodeJS ?
I'm afraid the documentation was somewhat jumping the gun. We do have users who have reported getting the code to run under Node.js, and we have done it ourselves "in the lab", but it requires source code tweaks to the issued product. As released, the code runs under two platforms, the browser platform and Nashorn (and under Nashorn, it assumes our test harness which is not released).
We're working on a version for Node.js. Doing this properly as a product needs a lot of functionality that isn't in the browser version, for example in XML parsing and serialization, debugging support, command line interfaces and APIs, etc.
Node.js Saxon-Js Instructions
This S/O question is the first listed on Google for "node.js saxon-js". So I'm answering this 4 years late because of the visibility.
[Terminal] npm install saxon-js
[IDE][xslt.js]
const saxonJs = require('saxon-js');
const fs = require('fs');
function transformDocument(source, destination, transformation, parameters) {
var xml = fs.readFileSync(source).toString()
var stylesheetParams = Object.getOwnPropertyNames(parameters)
.map(o => `QName('', '${o}') : '${parameters[o]}'`).join(",")
const html = saxonJs.XPath.evaluate(
`transform(
map {
'source-node' : parse-xml($xml),
'stylesheet-location' : $xslt,
'stylesheet-params': map {${stylesheetParams}},
'delivery-format' : 'serialized'
}
)?output`,
null,
{
params : {
'xml' : xml,
'xslt' : 'file:' + transformation
}
}
);
fs.writeFileSync(destination, html)
}
Parameters
source: xml file name
destination: output file name
transformation: xsl file name
parameters: regular json object containing any params for xslt
Characteristics
(-) extremely slow
(+) doesn't require running something on the command line every time the xslt file changes
(+) easy to use function signature based on xslt usage over the last 22 years
(+) doesn't crash
Notes
I didn't find any "Getting Started" for this. Not from Google, at least. I pieced together a working solution from multiple S/O answers.
This took me 3 hours. I hope this saves multiple developers 3 hours each.
I tried getting 'source-location' to work with a file: url, but no beans
sync I/O of course isn't necessary, it should work fine with async and nested callback functions. However, this isn't why its' slow. The xpath transform() function is quite slow, for some reason.
For some reason, this solution is stable and doesn't crash. Using Saxon-C over in Python keeps crashing, but this does not.
Related
(Using Sails.js)
I am testing webworker-threads ( https://www.npmjs.com/package/webworker-threads ) for long running processes on Node and the following example looks good:
var Worker = require('webworker-threads').Worker;
var fibo = new Worker(function() {
function fibo (n) {
return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1;
}
this.onmessage = function (event) {
try{
postMessage(fibo(event.data));
}catch (e){
console.log(e);
}
}
});
fibo.onmessage = function (event) {
//my return callback
};
fibo.postMessage(40);
But as soon as I add any code to query Mongodb, it throws an exception:
(not using the Sails model in the query, just to make sure the code could run on its own -- db has no password)
var Worker = require('webworker-threads').Worker;
var fibo = new Worker(function() {
function fibo (n) {
return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1;
}
// MY DB TEST -- THIS WORKS FINE OUTSIDE THE WORKER
function callDb(event){
var db = require('monk')('localhost/mydb');
var users = db.get('users');
users.find({ "firstName" : "John"}, function (err, docs){
console.log(("serviceSuccess"));
return fibo(event.data);
});
}
this.onmessage = function (event) {
try{
postMessage(callDb(event.data)); // calling db function now
}catch (e){
console.log(e);
}
}
});
fibo.onmessage = function (event) {
//my return callback
};
fibo.postMessage(40);
Since the DB code works perfectly fine outside the Worker, I think it has something to do with the require. I've tried something that also works outside the Worker, like
var moment = require("moment");
var deadline = moment().add(30, "s");
And the code also throws an exception. Unfortunately, console.log only shows this for all types of errors:
{Object}
{/Object}
So, the questions are: is there any restriction or guideline for using require inside a Worker? What could I be doing wrong here?
UPDATE
it seems Threads will not allow external modules
https://github.com/xk/node-threads-a-gogo/issues/22
TL:DR I think that if you need to require, you should use a node's
cluster or child process. If you want to offload some cpu busy work,
you should use tagg and the load function to grab any helpers you
need.
Upon reading this thread, I see that this question is similar to this one:
Load Nodejs Module into A Web Worker
To which Audreyt, the webworker-threads author answered:
author of webworker-threads here. Thank you for using the module!
There is a default native_fs_ object with the readFileSync you can use
to read files.
Beyond that, I've mostly relied on onejs to compile all required
modules in package.json into a single JS file for importScripts to
use, just like one would do when deploying to a client-side web worker
environment. (There are also many alternatives to onejs -- browserify,
etc.)
Hope this helps!
So it seems importScripts is the way to go. But at this point, it might be too hacky for what I want to do, so probably KUE is a more mature solution.
I'm a collaborator on the node-webworker-threads project.
You can't require in node-webworker-threads
You are correct in your update: node-webworker-threads does not (currently) support requireing external modules.
It has limited support for some of the built-ins, including file system calls and a version of console.log. As you've found, the version of console.log implemented in node-webworker-threads is not identical to the built-in console.log in Node.js; it does not, for example, automatically make nice string representations of the components of an Object.
In some cases you can use external modules, as outlined by audreyt in her response. Clearly this is not ideal, and I view the incomplete require as the primary "dealbreaker" of node-webworker-threads. I'm hoping to work on it this summer.
When to use node-webworker-threads
node-webworker-threads allows you to code against the WebWorker API and run the same code in the client (browser) and the server (Node.js). This is why you would use node-webworker-threads over node-threads-a-gogo.
node-webworker-threads is great if you want the most lightweight possible JavaScript-based workers, to do something CPU-bound. Examples: prime numbers, Fibonacci, a Monte Carlo simulation, offloading built-in but potentially-expensive operations like regular expression matching.
When not to use node-webworker-threads
node-webworker-threads emphasizes portability over convenience. For a Node.js-only solution, this means that node-webworker-threads is not the way to go.
If you're willing to compromise on full-stack portability, there are two ways to go: speed and convenience.
For speed, try a C++ add-on. Use NaN. I recommend Scott Frees's C++ and Node.js Integration book to learn how to do this, it'll save you a lot of time. You'll pay for it in needing to brush up on your C++ skills, and if you want to work with MongoDB then this probably isn't a good idea.
For convenience, use a Child Process-based worker pool like fork-pool. In this case, each worker is a full-fledged Node.js instance. You can then require to your heart's content. You'll pay for it in a larger application footprint and in higher communication costs compared to node-webworker-threads or a C++ add-on.
That's my setup. VS 2013, with the Node JS Tools, and Typescript. Adding a .ts file is handled without a hiccup. I am having some issues with the npm integration, but I've been able to work around them.
I've also added EdgeJS. It doesn't yet support TypeScript but I just write my EdgeJS calls with regular JS in my TS files. The problem is that EdgeJS allos you to write your CS functions a few different ways.
One way is like the following, where the entire body is enclosed in a comment block:
var hello = edge.func(function () {/*
async(input) => {
return ".NET welcomes " + input.ToString();
}
*/});
Unfortunately, the TS compiler, by default, removes these comments and I can't find a way in this project type to change that behavior.
Am I just out of luck (for now)?
To preserve comments for TypeScript, you'll need to start them on a new line. In the example you provided, the multi-line comment is not preserved as it starts on the end of a line with code.
Simply move the block comment start:
var edge = edge.func(() => {
/*
async(input) => {
}
*/
});
I am new to the 'nodejs' world.So wanting to explore the various technologies,frameworks involved i am building a simple user posts system(users posting something everybody else seeing the posts) backed by redis.I am using express framework which is recommended by most tutorials.But i have some difficulty in gettting data from the redis server i need to do 3 queries from the redis server to display the posts.In which case have to use neested callback after each redis call.So i wanted to use streamline.js to simplify the callbacks.But i am unable to get it to work even after i used npm install streamline -g and require('streamline').register(); before calling
var keys=['comments','timestamp','id'];
var posts=[];
for(var key in keys){
var post=client.sort("posts",'by','nosort',"get","POST:*->"+keys[key],_);
posts.push(post);
}
i get the error ReferenceError: _ is not defined.
Please point me in the right direction or point to any resources i might have missed.
The require('streamline').register() call should be in the file that starts your application (with a .js extension). The streamline code should be in another file with a ._js extension, which is required by the main script.
Streamline only allows you to have async calls (calls with _ argument) at the top level in a main script. Here, your streamline code is in a module required by the main script. So you need to put it inside a function. Something like:
exports.myFunction = function(_) {
var keys=['comments','timestamp','id'];
var posts=[];
for(var key in keys){
var post=client.sort("posts",'by','nosort',"get","POST:*->"+keys[key],_);
posts.push(post);
}
}
This is because require is synchronous. So you cannot put asynchronous code at the top level of a script which is required by another script.
As QA I use WSH scripts to do auto upload, deployment and some time Web testing in IE. WSH(wscript) with JavaScript can open IE window, activate it and access DOM model to do some actions or verify some expected results. It is kind of Selenium 1.0 approach but does not require JAVA and any envrionment configuration so can be executed on any developers/qa windows machine immidiately.
Recently I found NodeJS and all its abilities, except manipulating with Windows IE DOM. Cannot find the way on how to run my old WSH scripts to test IE DOM and at the same time use some NodeJS modules to parse XMLs or run test report server.
So question: is it possible to run WSH JavaScripts and Node.js and use all goodies from both worlds?
I am afraid, it is not, but hope somebody has workaround...
As workaround, maybe somebody found the way in NodeJS to start IE window access its DOM (...add own js script or run SendKeys to it)!?
I understand that NodeJS is not designed to do windows administrative tasks.
While not actually marrying as the question requires, #o_nix in the comments made the suggestion for https://github.com/idobatter/node-win32ole.
I'd suggest that this module satisfies many issues for people arriving here from Google (as I did).
It is also available from npm here: https://www.npmjs.com/package/win32ole
The module also has quite a few examples, such as:
https://github.com/idobatter/node-win32ole/blob/dev0.1.3/examples/activex_filesystemobject_sample.js
var win32ole = require('win32ole');
. . .
var withReadFile = function(filename, callback){
var fso = new ActiveXObject('Scripting.FileSystemObject');
var fullpath = fso.GetAbsolutePathName(filename);
var file = fso.OpenTextFile(fullpath, 1, false); // open to read
try{
callback(file);
}finally{
file.Close();
}
};
var withEachLine = function(filename, callback){
withReadFile(filename, function(file){
// while(file.AtEndOfStream != true) // It works. (without unary operator !)
// while(!file.AtEndOfStream) // It does not work.
while(!file.AtEndOfStream._) // *** It works. oops!
callback(file.ReadLine());
});
};
withEachLine(testfile, function(line){
console.log(line);
});
So, to me, this is as good as marrying old WSH scripts as anything. Tweaks will be involved of course, but then it's goodbye WSH.
More specifically, to the question at hand, this is a snippet of a demo IE script:
https://github.com/idobatter/node-win32ole/blob/master/examples/ie_sample.js
var win32ole = require('win32ole');
. . .
var ie = new ActiveXObject('InternetExplorer.Application');
ie.Visible = true;
for(var i = 0; i < uris.length; ++i){
console.log(uris[i]);
ie.Navigate(uris[i]);
win32ole.sleep(15000, true, true);
}
ie.Quit();
WSH is a different runtime and set of libraries from nodejs. The only simple solution I can think of for your use case is to use child_process to run your WSH scripts and capture the output and parse it.
The other options are:
Look at other browser automation modules - selenium is not your only option, there are also headless browsers, which may appease the situation: zombiejs, phantomjs etc
Write native bindings to the APIs used by WSH for nodejs
Merge the event loops of WSH and nodejs, and expose WSH's API to nodejs: not a good idea for such a narrow use case.
The benefit of firing a child process is that WSH is able to issue HTTP requests. And Node, obviously, can serve HTTP.
One can imagine a Node.js library that would completely proxy ActiveXObject that way and give Node.js all the same powers as WSH.
I'm thoroughly confused on how to use an npm module in Meteor client code.
I understand modules like fs would only work server-side, but in this case I'd like to use a simple text module like this for displaying pretty dates:
https://github.com/ecto/node-timeago
I've tried installing the module under /public/node_modules,
and it works great on the server-side following these instructions from SO: (
How do we or can we use node modules via npm with Meteor?)
Meteor.startup(function () {
var require = __meteor_bootstrap__.require
var timeago = require('timeago')
console.log(timeago(new Date()))
...
However it doesn't work in the client-side code:
if (Meteor.is_client) {
var require = __meteor_bootstrap__.require
var timeago = require('timeago')
console.log(timeago(new Date()))
...
Uncaught ReferenceError: __meteor_bootstrap__ is not defined"
Server-side is sort of useless for me in this case, as I'm trying to render text on the client.
I don't believe you need to use the server side version. Use the npm stuff for server side only and btw, put it in your /public/ as well. Who knows maybe you can call it once it is in your /public/, try it. Or try this.
Use something like the jquery timeago.js
Put it in /client/ or something like /client/js
Create a /client/helpers.js or some such.
Use a handlebars helper.
Handlebars.registerHelper('date', function(date) {
if(date) {
dateObj = new Date(date);
return $.timeago(dateObj);
}
return 'a long long time ago in a galaxy far away';
});
Example of calling 'date' handlebars helper function from template.
{{ date created }}
Where date is the handebars helper and created is the date coming out of the meteor/mongo collection.
See the github Britto project. That is where I got this code snippet and used it in a chat room app I wrote. Works fine.
There are a couple of others floating out there. Go to madewith.meteor.com and peruse the source of some of the projects.