Name

cx:polyglot — Evaluate steps implemented in other programming languages.

Synopsis

The cx:polyglot step leverages the GraalVM Polyglot Programming library to evaluate other programming languages as the implementations of steps.

Input portPrimarySequenceContent typesDefault binding
source✔ ✔  p:empty
program  text 
Output portPrimarySequenceContent typesDefault binding
result✔   
Option nameTypeDefault value
argsxs:string*()
cwdxs:string?()
languagexs:string()
optionsmap(xs:string,xs:string)?()
parametersmap(xs:QName,item()?)?()
result-content-typexs:string?()
variablesmap(xs:string,item()?)?()
This is an extension step; to use it, your pipeline must include its declaration. For example, by including the extension library with an import at the top of your pipeline:
<p:import href="https://exproc.org/library/polyglot.xpl"/>
Declaration
 1 |<p:declare-step xmlns:cx="http://xmlcalabash.com/ns/extensions"
   |                xmlns:p="http://www.w3.org/ns/xproc"
   |                type="cx:polyglot">
   |   <p:input port="source" primary="true" sequence="true">
 5 |      <p:empty/>
   |   </p:input>
   |   <p:input port="program" content-types="text"/>
   |   <p:output port="result"/>
   |   <p:option name="language" as="xs:string"/>
10 |   <p:option name="cwd" as="xs:string?"/>
   |   <p:option name="args" as="xs:string*"/>
   |   <p:option name="result-content-type" as="xs:string?"/>
   |   <p:option name="variables" as="map(xs:string,item()?)?"/>
   |   <p:option name="parameters" as="map(xs:QName,item()?)?"/>
15 |   <p:option name="options" as="map(xs:string,xs:string)?"/>
   |</p:declare-step>
Errors
CodeDescription
cxerr:XI0047It is a dynamic error (cxerr:XI0047) if more than one input appears on the source port.

Installation

The cx:polyglot step is not included in the standard XML Calabash release. You must obtain it separately and install it on your classpath before you can use this step. (More detailed instructions, T.B.D.)

Description

Note

The signature for this step was substantially changed in XML Calabash 3.0.26. In particular the meaning of the parameters option has changed.

The polyglot extension includes cx:javascript and cx:python for running JavaScript and Python scripts, respectively. Other languages are possible if the dependencies are installed and GraalVM is configured appropriately, including Ruby, R, and Java.

If a document appears on the source port, it will be serialized and will appear on standard input for the program. It is a dynamic error (cxerr:XI0047) if more than one input appears on the source port.

The language option must be a GraalVM language identifier. For the cx:javascript and cx:python steps, this is set automatically.

The program text must appear on the program port. The step will fail if the input is not syntactically correct for the specified language.

The value of the args option will be passed as the arguments to the program. The first argument passed to scripts is conventionally the name of the script executable. The polyglot step sets that to the base URI of the invoking step.

The result-content-type controls how the script returns a value.

The variables option is used to initialize the in-scope variables for the script. The values are converted to language-appropriate values where possible. XML values are serialized and passed as strings.

The options are passed to the runtime context builder. See the GraalVM documentation for more details about available options.

If the cwd option is used, the specified path will be used as the current working directory for the evaluation of the program.

If the script ends with an non-zero exit code, the step will fail.

Parameters

The parameters option can be used to set parameters on the context builder. The following parameters are supported:

allowAllAccess (boolean)

Sets the all access parameter.

allowCreateProcess (boolean)

Sets the create process parameter.

allowCreateThread (boolean)

Sets the create thread parameter.

allowEnvironmentAccess (“ALL”, “INHERIT”)

Sets the environment access parameter.

allowExperimentalOptions (boolean)

Sets the experimental options parameter.

allowIO (“NONE”, “ALL”)

Sets the allow IO parameter.

allowInnerContextOptions (boolean)

Sets the allow inner context options parameter.

allowNativeAccess (boolean)

Sets the allow native access parameter.

allowPolyglotAccess (“NONE”, “ALL”)

Sets the polyglot access parameter.

allowValueSharing (boolean)

Sets the allow value sharing parameter.

environment (map(xs:string,xs:string))

Sets environment variables for the program.

sandbox (“TRUSTED”, “CONSTRAINED”, “ISOLATED”, “UNTRUSTED”)

Sets the sandbox policy.

Consult the GraalVM documentation for more information about the parameters.

Returning values

There are two ways to return a value: directly as the last expression in the script, or by writing the result to standard output.

Direct results

If there is no result-content-type, the step assumes that the result will be returned directly by the script.

Returning results from a script is a bit unorthodox; scripts don’t usually return anything except an exit code. The GraalVM library treats the last expression in the script as the return value. For example, this Python script “returns” the number 42.

  |print("It doesn’t matter what you do here")
  | 
  |42

The advantage of using direct results is that they don’t have to be serialized and reparsed. Direct results can only be atomic values, maps, and arrays.

🛑
Warning

The GraalVM library always returns something from your script. If you don’t provide a final expression, the resulting value is likely to be uninterpretable. (It will probably appear to be a map that contains non-XML characters.)

Always return something.

On standard output

If a result-content-type is specified, the step assumes that the result will be written to standard output. The result of the step will be the text that appears on standard output interpreted according to the result-content-type.

This is the only way to return XML.

Dependencies

To use the polyglot steps, you must use GraalVM 21.0.2 or a compatible release. You will also need to include the extension dependency:

  • com.xmlcalabash:polyglot:3.0.27

The following third-party dependencies will be included transitively:

  • org.graalvm.polyglot:js:23.1.5
  • org.graalvm.polyglot:polyglot:23.1.5
  • org.graalvm.polyglot:python:23.1.5