Can you use variables for Javascripts in do javascript?

Can you do something like this:

tell application "Safari"
	set myScript to "alert ('hello world')"	
	do JavaScript myScript with arguments {1,2}
end tell

(This doesn’t work due to {1,2})

No. Where would the arguments even be used with your example?

There’s very little point to passing parameters to a JavaScript script from AS. First, JS only accepts parameters in functions. Second, one has to pass the script as a string anyway, and that string can easily be written to contain the parameters.
If there’s a need to run the same code with different parameters, one could write a function/handler which uses the parameters to create the script string accordingly.

The main question though remains: what is the goal?

What is the relation between “JavaScript” and “XMLRPC” here? If I understand the OP correctly (and I’m not at all sure of that), they want to use the JavaScript capabilites of certain apps, like Safari, Chrome and perhaps Adobe apps. Which role could XMLRPC possibly play there?
Although you’re very fond of XMLRPC: XML is at best a second-class citizien in JavaScript. If one would want to serialize data, JSON would be the way to go – not XML, since there’s no XML support built into JS. And in the times of loosely coupled web services (think REST), XMLRPC is very much a duck dead in the water.

First off, there is no “RPC protocol”. RPC stands for remote procedure call, and there are tons of implementations. Second, the goal of RPC was not to pass parameters from one language to another – RPC is completely language agnostic. It is meant to call procedures in another process, either on the same machine or across the network, having these procedures do something and possibly return a value. Which required originally a lot of marshalling and stuff just to make very simple things work. It’s easier with XMLRPC (or JSONRPC) since that only sends strings.

To couple different languages on a machine, one would use a bridge (like ASObjC) which takes care of parameter mapping, calling conventions and all that. That’s old stuff, even 40 years ago we could call C functions from Fortran with some massaging. And that was certainly faster than any messaging implementation.

Finally: There is no “JavaScript” per se. It is always embedded into something else, so to “send parameters to JavaScript” is at best under-specified, et worst nonsense. You could perhaps send JS code to another program to execute it. Or you could have a JS server running somewhere and waiting for connections (in which case you’d send it messages, very much as with XMLRPC).

In my case I want to send different XPaths to a Javascript. After posting this question I realised that with arguments seems to be an Adobe specific thing. I saw a few examples using that, without mentioning that it was Adobe-specific.

The terminology seems a bit off. You can execute JavaScript, for example, in a browser. For that, you have to send the complete script to this other program. Do you mean that? And could you please be more specific, as to what you want to achieve other than simply “sending an XPath”?

“Sending an XPath to a JavaScript” would only (vaguely) make sense if there were a kind of server running on the receiving and which in turn would pass on said parameters to a JavaScript function.

As I said, I’d write a function or handler receiving the parameters and generating the complete(!) JavaScript code that the other program should run. In JavaScript itself, you could use a template string, something like

const parent="tbody";
const child="tr";
const app = Application("Safari");
const script1 = `document.execute("//${parent}/${child}")`

OTOH, if you’re after HTML elements, I’d go for querySelector(All) and CSS selectors. I posted an example here

I left out the words “execute” and “as an argument”.

I have an AS that refers to/includes a JS. The JS is executed in Safari with an XPath as the argument. The purpose is to extract all nodes that matches the XPath as an array and return that array to the AS. The AS then creates a CSV from that.

I suppose that you have to return the array as a string and reassemble a list in AS from that again.

If you were using JS instead of AS, you could use JSON to return the result and convert it to an array again.

It is actually a two step process, where both steps consists of an AS sending a JS to Safari extracting data using XPaths. In the first step I am extracting URLs (so they can be handled like a string with just some delimiter inbetween them). In the second step I am opening every URL and extracting a handful of datafields. They can be returned as a string with a comma between the fields. I will then add that string as a newline in my CSV.

The problem now is that the JS function document.evaluate don’t seem to work. I get TypeError in the Safari console when executing it. Safari seems very picky about how to declare variables (let, var or “undelcared”), but in an inconsistent way?

The function works, and Safari is not inconsistent in its handling of variable scope etc. Please post your code and the relevant URL(s), otherwise one can’t help you. And it’s really overly time-consuming to have to come back and ask for details you should be providing upfront if you’re looking for help.

Aside: Why does it have to be XPath? I’d rather go for the well documented DOM methods that were written for what you seem to want to do. Also, you do not need to steps with the appropriate JS function: Just use XHR to load the stuff from the URLs and extract the data fields.

What DOM-methods are you thinking of?

querySelectorAll for example. But if the page is loading the data dynamically, that alone doesn’t help. Them you might have to scroll to the end programmatically.

That’s neither here nor there. I’ve seen modular programming thrown at every conceivable problem, then OO programming, functional programming, patterns, aspect-oriented programming, intentional programming… It’s always the same: One paradigm that is supposedly able to solve every problem.
And now I’m old enough to know that this simply does not work. There are problems where OO is good, there are problems where functional programming are good, and there might be problems where XMLRPC are good.
Talking to a browser is not one of these problems. That’s just using a hammer to drive in a screw – yes, the screw will be driven in. But there are better tools to achieve this goal.

BTW: No need to patronize me – I’ve read about SunRPC ages ago, and even they didn’t purport it to solve each and every problem. Also, AS being implemented on top of IPC does not mean that it’s the holy grail. It is, in my opinion, a piece of outdated, verbose and underspecified software that I’d like to see go away sooner rather than later.

I’d like it to be replaced with anything more modern and working. While JavaScript as such fulfills both criteria, JXA fails miserably with the second because Apole didn’t finish it.

But in most cases, JXA is easier to write and more compact for the same functionality than AS. The node module node_automation might be a good solution, but I have only very limited experience with it.

And it’s already possible to script in Swift. JS has the advantage of being useful in other contexts, too.

I want to scroll all the way down here and extract the URL to all my Facebook friend’s profile page.

In the next step I want to open all the profile pages and extract some data from them that I then will concatenate to a string (a CSV).

Currently I am stuck on the first step, I can’t get any data back from the Javascript.

A simple code example:

tell application "Safari"
	open location ""
	delay 5
	set selectedText to "hello world"
	log selectedText
	set selectedText to do JavaScript "document.evaluate('//div/div[1]/div/div[3]/div/div/div/div[1]/div[1]/div[1]/div/div/div[1]/div[2]/div/div/a/@href', document, null, 0, null)" in front document
	log selectedText
end tell

results in

error "The variable selectedText is not defined." number -2753 from "selectedText"

I don’t use Facebook nor do I have an account there. Try to run you JS code in the developer console of your browser – what does it give you?

Sorry for taking a screenshot but it is difficult to copy-paste text from the browser console in a way that resembles the actual session:

The xpath seems to work (see the $x execution) but the result from document.evaluate is more ambiguous. I don’t know how interpret it.

You could try setting the result type parameter to 2 (string), see here

Also, I’d use DOM methods and querySelector which gives you a Node whose innerText you can return to your AS.

See here

For an example