2. Running XED scripts in a macro

The script element allows to a run a XED script in the context of a macro.

<script
  location = anyURI
  context = XPath expr. returning a node set : "/"
  argument0 = XPath expression
  argument1 = XPath expression
  argument2 = XPath expression
  argument3 = XPath expression
  argument4 = XPath expression
  argument5 = XPath expression
  argument6 = XPath expression
  argument7 = XPath expression
  argument8 = XPath expression
  argument9 = XPath expression
><![CDATA[
  XED source
]]></script>

XED is a very small, very simple scripting language, leveraging the native XPath 1.0 implementation of XMLmind XML Editor, allowing to modify in place the document being edited. The reference manual of XED is found in Part II, “The XED scripting language” in XMLmind XML Editor - Support of XPath 1.0.

The source of the script

The source of the XED script may be found inside the script element. In such case, it's strongly recommended to use a CDATA section.

If the source of the XED script is not found inside the script element, then the location attribute is considered. This attribute must point to an external text file, typically having a .xed extension, containing the source of the script. External XED scripts are cached, therefore this is almost no performance penalty for using external script files.

The main difference between using an internal XED script and using an external XED script is that an internal XED script automatically inherits all the namespace declarations, except the default namespace declaration, which are in scope with the script element. Example:

<configuration
  xmlns="http://www.xmlmind.com/xmleditor/schema/configuration"
  xmlns:cfg="http://www.xmlmind.com/xmleditor/schema/configuration">
  ...
        <script>
          ...
        </script>

is equivalent to:

<configuration
  xmlns="http://www.xmlmind.com/xmleditor/schema/configuration"
  xmlns:cfg="http://www.xmlmind.com/xmleditor/schema/configuration">
  ...
        <script>
          namespace cfg="http://www.xmlmind.com/xmleditor/schema/configuration";
          ...
        </script>

Storing different scripts in the same XED script file

Note that the URI contained in the location attribute may have a fragment. This fragment specifies the name of the XED macro-command in XMLmind XML Editor - Support of XPath 1.0 to be executed.

This allows to store different scripts —that is, several unrelated XED macro-commands— in the same script file. Example: script file hello.xed contains 2 XED macros:

macro sayHello() {
    message("Hello world!");
}

macro sayGoodbye() {
    message("Goodbye world!");
}

The following XXE macro-command allows to invoke sayGoodbye() found in script file hello.xed:

<command name="sayGoodbye">
  <macro>
    <sequence>
      <script location="hello.xed#sayGoodbye" />
    </sequence>
  </macro>
</command>

An equivalent XXE macro-command would be:

<command name="sayGoodbye">
  <macro>
    <sequence>
      <script>
      include "hello.xed";
      sayGoodbye();
      </script>
    </sequence>
  </macro>
</command>

Passing arguments to the script

Attributes argument0 to argument9 are evaluated as XPath expressions in the context of the node specified using the context attribute. The results of the evaluations are passed to the script by the means of global variables script-argument0 to script-argument9.

If, for any reason, the evaluation of argumentI fails, the script is nevertheless evaluated. Simply global variables script-argumentI are not defined. That's why these arguments are typically used as follows:

set-variable("myOption", defined("script-argument7", "off"));

If variable script-argument7 is defined, use its value, otherwise use string "off". See XPath extension function defined() in XMLmind XML Editor - Support of XPath 1.0.

Returning a value from the script

The result of a script is specified in global variable script-result. The result of a script may be used in the subsequent commands contained in the macro by the means of the "%_" special variable. If a script does not set global variable script-result, then this script will not change the value of "%_" special variable.

Example:

<command name="SayHello">
  <macro>
    <sequence>
      <script>
        set-variable("script-result", "Hello world!");
      </script>

      <command name="alert" parameter="%_"/>
    </sequence>
  </macro>
</command>

Changing the node or text selection from within the script

After it has been run, a script may affect the node or text selection by setting the following global variables:

VariableValueDescription
script-selectednode setSelects first node of the node set.
script-selected2node setExtends node selection to the first node of the node set.
script-dotnode set whose first node is a textual nodeMoves the caret inside the first node of the node set. This first node must be a textual node of any kind (text, comment, processing instruction).
script-dot-offsetpositive number; defaults to 0Specifies the offset of the caret within the textual node obtained using variable script-dot.
selected-marknode set whose first node is a textual nodeMove the text selection mark inside the first node of the node set. This first node must be a textual node of any kind (text, comment, processing instruction).
script-mark-offsetpositive number; defaults to 0Specifies the offset of the text selection mark within the textual node obtained using variable script-mark.

It's possible to clear a selection mark of any kind but the caret, by setting the corresponding variable to an expression which does not evaluate to a node set. Examples: set-variable("script-selected2", ""), set-variable("script-mark", false()).

Otherwise, if the value of any of the above global variables has an unusable type (e.g. for script-dot, an empty node set or a node set not starting with a textual node), then this variable is simply ignored and no error is reported.

Setting script-dot (respectively script-mark) without setting script-dot-offset (respectively script-mark-offset) cause the caret (respectively the text selection mark) to be located at offset 0.

Caveats and pitfalls