XQuery Modules in Fonto

Fonto Editor supports the usage of XQuery modules. These modules will be automatically loaded and their publicly declared variables and functions can then be used in any other XPath context within Fonto Editor.

Creating an XQuery module

XQuery modules are files with an .xqm extension. XQuery modules must be places in the src directory of a package and will be registered and loaded automatically. The publicly declared functions and variables are thus automatically available in any other XQuery context in Fonto Editor.

Contents of an XQuery module

An XQuery module must have a module declaration in Fonto Editor. This declaration tells the XPath/XQuery engine that this file is an XQuery library module. This declaration also declares the namespace for the variables and functions defined in the module.

XQuery modules declare functions and variables into a namespace. All functions that are part of the Fonto SDK reside in the http://www.fontoxml.com/functions namespace URI. Fonto Editor binds the fonto prefix to this namespace URI. Functions and variables declared on the application level must use their own namespace.

Module declaration example

XQuery

module namespace example = "http://example.com";

A module declaration. The namespace URI http://example.com and namespace prefix example can be changed to your application's namespace URI and prefix.

Note that this declaration does not use the assignment operator (:=) you may know from using XPath and XQuery variables.

Check out our concept page on handling namespaces in Fonto Editor for more information on namespaces in both XML documents and XPath and XQuery.

Function and variable declarations follow the module declaration.

Public function declaration example

XQuery

declare %public function example:get-string () as xs:string {
	"example string"
};

A public function declaration. A function called get-string is declared in the namespace http://example.com. The function returns a string. Note that the aforementioned namespace prefix is used here. The function body is a regular XPath/XQuery expression, in this case a string literal.

Public variable declaration example

XQuery

declare %public variable example:var-name as xs:string := "example variable string";

A public variable declaration. A variable called var-name is declared in the namespace http://example.com. The variable has the type xs:string. Note that the aforementioned namespace prefix is used here.

Using functions and variables declared in XQuery modules

Once you have created an XQuery module, you can use the functions and variables declared in it anywhere in your editor configuration. This works because all queries in Fonto Editor are run in an XQuery context, and thus allow you to use functions and variables declared in XQuery modules.

The following examples show you how to use functions and variables declared in XQuery

Evaluate XPath

You can use functions and variables declared in XQuery modules in queries you evaluate using one of the evaluateXPath functions.

evaluateXPathToString example

JavaScript

const result = evaluateXPathToString(
	`import module namespace app="http://example.com";
	example:get-string()`,
	null,
	readOnlyBlueprint
);

This example shows how a function declared in an XQuery module can be used in a evaluateXPathToString call.

Don't forget the import module statement!

Operations

You can use functions from your XQuery module in operations. Operations allow you to run XPath/XQuery queries in their data properties by using the x__ prefix. Be sure to import the namespace you declared your functions and variables in.

Operation example with inline module import

JSON

{
	"operation-name": {
		"steps": {
			"type": "operation/append-structure",
			"data": {
				"contextNodeId": "{{contextNodeId}}",
				"childNodeStructure": "x__import module namespace fonto = 'http://www.fontoxml.com/functions'; <someNewElement with='attributes'>And some text</someNewElement> => fonto:serialize-as-jsonml()"
			}
		}
	}
}

This example shows how a function declared in an XQuery module can be used to generate a child node structure for the append-structure operation.

Operation example with global module import

JSON

{
	"__moduleImports__": {
		"fonto": "http://www.fontoxml.com/functions"
	},
	"my-special-operation": {
		"steps": {
			"type": "operation/append-structure",
			"data": {
				"contextNodeId": "{{contextNodeId}}",
				"childNodeStructure": "x__<someNewElement with='attributes'>And some text</someElement> => fonto:serialize-as-jsonml()"
			}
		}
	}
}

This example is the same as the example above. However, instead of importing the module inline, it is imported globally for the whole operations.json file.

Other XQuery modules

You can use functions defined in other XQuery modules in your own module. You can do this by importing the other module in your module.

You can only use functions and variables declared in other packages which are loaded before the package containing your XQuery module. This means that your package should depend on the package which contains the XQuery module you would like to use.

Load order is also important when using functions and variables declared in an XQuery module in the same package as your XQuery module. XQuery modules are loaded in an alphabetical order. This is currently a limitation. This means that XQuery module b.xqm can import XQuery module a.xqm, but not the other way around.

XQuery module importing another module

XQuery

module namespace example = "http://example.com";

import module namespace another-example = "http://another-example.com";

declare %public function example:get-string () as xs:string {
	"prefix-" || another-example:get-string()
};

This example shows how you can import another module in an XQuery module. This example uses the string concatenation operator.

Using custom XPath functions in an XQuery module

You can use custom XPath functions, those registered with registerCustomXPathFunction, in your XQuery module. To do this, you will have to declare the function you want to use in your XQuery module as an external function.

XQuery module using a custom XPath function

XQuery

declare function example:get-custom-string () as xs:string external;

Declaring a function as external tells the XPath/XQuery engine that this function exists, but may not yet be declared or registered.