Loading TOC...
JavaScript Reference Guide (PDF)

JavaScript Reference Guide — Chapter 2

MarkLogic JavaScript Object API

This chapter describes the Object API built into Server-Side JavaScript in MarkLogic and includes the following sections:

Node and Document API

MarkLogic APIs often return or expect nodes and/or documents. To make it easy to use these APIs in JavaScript, MarkLogic has added the built-in Node and Document objects. These are objects but they are not part of the global object. This section describes the interface for these objects and includes the following parts:

Node Object

A Node can be any kind of node, such as an element node, a document node, a text node, and so on. If a function returns a Node in Server-Side JavaScript, you can examine the Node object using the following properties:

Property Description
baseURI
A String representing the base URI of the node.
valueOf()
The atomic value of the node.
nodeType
A number representing the type of the Node object. The following are meanings the possible values of nodeType:
ELEMENT_NODE
1
ATTRIBUTE_NODE
2
TEXT_NODE
3
PROCESSING_INSTRUCTION_NODE
7
COMMENT_NODE
8
DOCUMENT_NODE
9
BINARY_NODE
13
NULL_NODE
14
BOOLEAN_NODE
15
NUMBER_NODE
16
ARRAY_NODE
17
OBJECT_NODE
18
toObject()
JavaScript object if the node is type Array, Boolean, Number, Object or Text; otherwise it is Undefined.
xpath(String   XPathExpression,
  Object NamespaceBindings)
Evaluate the XPath expression. The first argument is a string representing the XPath expression, and the second argument is an Object where each key is a namespace prefix used in the first argument, and each value is the namespace in which to bind the prefix. For the XPath expression, if you want the expression evaluated relative to the current node, start the path with a dot (.); for example, "./my-node". Note that xpath returns a Sequence if the expression matches more than one node.

For additional DOM properties available on XML nodes (document, element, attribute, processing instruction, and comment), see Node Object for XML Nodes.

The following is an example of using the xpath function on a Node object. The cts.doc function returns a Node, specifically a Document node, which inherits an xpath method from Node. The second parameter to Node.xpath binds the XML namespace prefix bar to the XML namespace URI bar.

// assume a document created as follows:
declareUpdate();
xdmp.documentInsert("/my/doc.xml", fn.head(xdmp.unquote(
  '<bar:foo xmlns:bar="bar"><bar:hello><bar:goodbye \n\
     attr="attr value">bye</bar:goodbye>\n\
  </bar:hello>\n\
</bar:foo>')));

// Use the Node.xpath method on the document node:
const node = cts.doc("/my/doc.xml");
node.xpath("//bar:goodbye/@attr", {"bar":"bar"});

// Running in Query Console displays the following value (as an
// attribute node): "attr value" 

Document Object

The Document object inherits all of the properties from the Node Object above, and has the following additional properties:

Property Description
documentFormat
A string representing the format of the document node. The following are the meanings of the possible values of documentFormat:
BINARY
"BINARY"
JSON
"JSON"
TEXT
"TEXT"
XML
"XML"
root
The root node of the document.

XML DOM APIs

MarkLogic implements XML DOM APIs to provide read-only access to XML nodes. This section describes these APIs and includes the following parts:

Node Object for XML Nodes

In addition to the Node properties described in Node Object, the XML node types all have a subset of the W3C DOM API of Node, as follows:

Properties Description
childNodes
An Iterator that contains all children of this node.
firstChild
The first child of this node. If there is no such node, returns null. Note that it returns the first child node of any kind, not just the first element child, so if the first child is a text node with empty space in it that is what is returned.
lastChild
The last child of this node. If there is no such node, returns null. Note that it returns the last child node of any kind, not just the last element child, so if the last child is a text node with empty space in it that is what is returned.
localname
Returns the local name part of the qualified name (QName) of this node. For nodes of any type other that ELEMENT_NODE or ATTRIBUTE_NODE, this always returns null.
namespaceURI
The namespace URI of this node, or null if it is unspecified. For nodes of any type other that ELEMENT_NODE or ATTRIBUTE_NODE, this always returns null.
nextSibling
The node immediately following this node. If there is no such node, returns null.
nodeName
The name of this node, depending on its type.
nodeValue
The value of this node, depending on its type.
ownerDocument
The document the node belongs to.
parentNode
Node that is the parent of the node.
prefixSibling
Node representing the previous node in the tree, or null if no such node exists.
hasChildNodes()
Boolean indicating if the node has child nodes.
hasAttributes()
Boolean indicating if the node has any attributes.
attributes
NamedNodeMap of all the attributes, if any. For nodes of any type other than ELEMENT_NODE this map will be empty.
baseURI
The base URI of this node, if any.
textContent
Like fn.string on the node except that document nodes are null.
isSameNode(
  Node other)
Returns true if the two nodes are the same (similar to the XQuery operator = on nodes).
isEqualNode(
  Node other)
Returns true if the two nodes are the equal (similar to the XQuery fn:deep-equals, but treating everything as untyped).
insertBefore(
  Node newChild,
  Node refChild)
Raises NO_MODIFICATION_ALLOWED error.
replaceChild(
  Node newChild,
  Node oldChild)
Raises NO_MODIFICATION_ALLOWED error.
removeChild(
  Node oldChild)
Raises NO_MODIFICATION_ALLOWED error.
appendChildNodes(
  Node newChild)
Raises NO_MODIFICATION_ALLOWED error.
normalize()
Does nothing (MarkLogic documents are already normalized).

The DOM APIs provide read-only access to the XML nodes; any DOM APIs that attempt to modify the nodes will raise the DOM error NO_MODIFICATION_ALLOWED_ERR.

Document Object for Document Nodes

The Document object inherits all of the properties from the Node Object for XML Nodes above (in addition to the properties from the Node Object), and has the following additional properties:

Properties Description
documentElement
Element that is the direct child of the document.
documentURI
The URI of the document.
getElementsByTagName(
  String tagname)
NodeList of elements in the document with the given tag name, in document order. The tag name is a string. If it includes a colon, it will match as a string match with the exact prefix. The getElementsByTagNameNS function is preferred for namespaced elements.
getElementsByTagNameNS(
  String namespaceURI,
  localname)
NodeList of elements in document with the given namespace URI and local name, in document order. A null value for the namespace URI signifies no namespace.
getElementById(
  String elementId)
Element that has the given ID, if any.
importNode(
  Node importedNode, 
  Boolean deep)
Raises NO_MODIFICATION_ALLOWED error.
normalizeDocument()
Does nothing (MarkLogic documents are already normalized).

NodeBuilder API

The NodeBuilder API makes it easy to construct nodes in JavaScript, including XML nodes and JSON nodes, and has the following functions and properties:

Functions/Properties Description
addAttribute(String name,
  String value,
  [String URI])
Add a new attribute to the current element being created. You cannot create duplicate attributes; if an attribute with that name already is present in the element, XDMP-DUPATTR is thrown.
addComment(String text)
Add a comment node to the current parent node being created.
addDocument(String text,
  [String URI]))
Add a document with the given URI and the specified text content. This results in a document of format text (that is, document node with a text node root).
addDocument(
  Function content,
  [String URI]))
Add a document with the given URI. The function will be given the builder as its argument and evaluated to produce the content. For example:
const x = new NodeBuilder();
const b = x.addDocument(
  function(builder){
    builder.addElement("foo", 
      "some stuff")});
b.toNode().root;
=>
<foo>some stuff</foo>
addElement(String name,
  String text,
  [String URI])
Add an element to the current parent node with the specified name, text content, and namespace URI. The function will be given the builder as its argument and evaluated to produce the content. The element creation is completed after calling addElement, and consequently subsequent calls to addAttribute would not apply to this element.
addElement(String name,
  Function content,
  [String URI])
Add an element to the current parent node with the specified name and namespace URI. The element creation is completed after calling addElement, and consequently subsequent calls to addAttribute would not apply to this element. The function in the second argument will be given the builder as its argument and evaluated to produce the content. For example:
const x = new NodeBuilder();
const b = x.addElement("foo", 
  function(builder){
    builder.addText("some stuff")});
b.toNode();
=>
<foo>some stuff</foo>
addNode(Node node)
Add a copy of the specified node to the current parent node.
addProcessingInstruction(
  String target,
  String text)
Add a processing instruction node to the current parent node with the specified target and text.
addText(String value)
Add a text node to the current parent node being created.
addBinary(String hex)
Add a binary node to the current parent node being created. The argument is a hex encoded string.
addNumber(Number val)
Add a number node to the current parent node being created.
addBoolean(Boolean val)
Add a boolean node to the current parent node being created.
addNull()
Add a null node to the current parent node being created.
endDocument()
Complete creation of the document.
endElement()
Complete creation of the element.
startDocument([String URI])
Start creating a document with the specified URI.
startElement(String name,
  [String URI])
Start creating an element as a child of the current document or element with the specified name and (optionally) namespace URI.
toNode()
Returns the constructed node.

In order to use anything created with NodeBuilder as a node, you must first call toNode().

The following is an example of creating an XML document node:

const x = new NodeBuilder();
x.startDocument();
x.startElement("foo", "bar");
x.addText("text in bar");
x.endElement();
x.endDocument();
const newNode = x.toNode();
newNode;
// returns a document node with the following serialization:
// <?xml version="1.0" encoding="UTF-8"?>
// <foo xmlns="bar">text in bar</foo>

Element

The following properties and functions are available on element nodes:

Properties/Functions Description
tagName
Qualified name of the element.
getAttribute(String name)
Returns an attribute value by name.
getAttributeNode(String name)
Returns an attribute node (Attr) by name.
getAttributeNS(
  String namespace,
  String name)
Returns the value of the attribute with the specified namespace and name, from the current node.
getAttributeNode(String name)
Return the named attribute of this element, if any, as a node.
getAttributeNodeNS(
  String namespaceURI,
  String localname)
Return the attribute of this element with a matching namespace URI and local name.
getElementsByTagName(
  String tagname)
NodeList of element descendants of this element with the given tag name, in document order. The tag name is a string. If it includes a colon, it will match as a string match with that exact prefix. getElementsByTagNameNS is preferred for namespaced elements.
getElementsByTagNameNS(
  String namespaceURI,
  String localname)
NodeList of element descendants with the given namespace URI and local name, in document order. A null value for the namespace URI signifies no namespace.
hasAttribute(String name)
Returns true if the element has the named attribute.
hasAttributeNS(
  String namespaceURI,
  String localname)
Returns true if the element has an attribute with the given namespace URI and local name.
schemaTypeInfo
TypeInfo of the element.
setAttribute(String name,
  String value)
Raises NO_MODIFICATION_ALLOWED error.
removeAttribute(String name)
Raises NO_MODIFICATION_ALLOWED error.
setAttributeNode(Attr newAttr)
Raises NO_MODIFICATION_ALLOWED error.
removeAttributeNode(
  Attr newAttr)
Raises NO_MODIFICATION_ALLOWED error.
setAttributeNS(
  String namespaceURI,
  String localname)
Raises NO_MODIFICATION_ALLOWED error.
removeAttributeNS(
  String namespaceURI,
  String localname)
Raises NO_MODIFICATION_ALLOWED error.
setIdAttribute(
  String name,
  Boolean isId)
Raises NO_MODIFICATION_ALLOWED error.
setIdAttributeNS(
  String namespaceURI,
  String localname,
  Boolean isId)
Raises NO_MODIFICATION_ALLOWED error.
setIdAttributeNode(
  Attr idAttr,
  Boolean isId)
Raises NO_MODIFICATION_ALLOWED error.

Attr

The following properties are available on attribute (Attr) nodes, in addition to the XMLNode properties which it inherits:

Properties Description
name
Qualified name of this attribute.
specified
Boolean indicating whether the attribute is explicit (true) or defaulted from the schema (false).
value
Value of this attribute, as a string.
ownerElement
Element that has the attribute.
isId
Boolean indicating whether this is an ID attribute. (It has the type xs:ID).
schemaTypeInfo
TypeInfo of the element.

The Attr object is being deprecated in DOM4.

CharacterData and Subtypes

The CharacterData inherits all of the APIs from an XMLNode plus the following additional properties and methods. It has subtypes that inherit from Text node, Comment nodes, and Processing Instruction nodes, which are also included in the table.

Functions/Properties Description
data
The textual content of the node (same as fn:data).
length
The number of characters in the textual content of the node.
substringData(Number offset,
  Number count)
Substring of the textual content, starting at the given character offset and continuing for the given number of characters.
isElementContentWhitespace
True if the Text node is ignorable whitespace. In a MarkLogic context this is almost always false as MarkLogic strips ignorable whitespace on ingest. It can be true of data were ingested before a schema for it was loaded. (Text node only).
wholeText
Returns the value of this node concatenated with logically adjacent text nodes. For MarkLogic, because it already combines logically adjacent text nodes, this is just the value of the node itself. (Text node only)
target
The target of the processing instruction. For example, given the PI <?example something?>, example is the target and something is the data.
appendData(String arg)
Raises NO_MODIFICATION_ALLOWED error.
insertData(Number offset,
  Number count)
Raises NO_MODIFICATION_ALLOWED error.
deleteData(Number offset,
  Number count)
Raises NO_MODIFICATION_ALLOWED error.
replaceData(Number offset,
  Number count, 
  String arg)
Raises NO_MODIFICATION_ALLOWED error.
replaceWholeText(
  String content)
Raises NO_MODIFICATION_ALLOWED error. (Text node only)
splitText(Number offset)
Raises NO_MODIFICATION_ALLOWED error. (Text node only)

TypeInfo

The following are the functions and properties of TypeInfo. Additionally, it has the schema component methods bound to it.

Functions/Properties Description
typeName
The local name of the type.
typeNamespace
The namespace URI of the type.
isDerivedFrom(
  String typeNamespace,
  String typeName,
  unsigned long
    derivationMethod)

Returns true if this type is derived from the type named by the arguments. The derivation method argument is a flag indicating acceptable derivation methods (0 means all methods are acceptable). The flag values that may be combined are:

DERIVATION_RESTRICTION (0x1)

DERIVATION_EXTENSION (0x2)

DERIVATION_UNION (0x4)

DERIVATION_LIST (0x8)

NamedNodeMap

The following are the functions and properties of NamedNodeMap.

Functions/Properties Description
length
Number of nodes in the map.
getNamedItem(name)
Returns the node in the map with the given name, if any. getNamedItemNS is preferred for namespaced nodes.
getNamedItemNS(
  String namespaceURI,
  String localName)
Returns the node in the map with the given namespace URI and local name.
item(Number index)
Get the node at the index place (first, second, and so on).
setNamedItem(Node arg)
Raises NO_MODIFICATION_ALLOWED error.
removeNamedItem(
  String name)
Raises NO_MODIFICATION_ALLOWED error.
setNamedItemNS(Node arg)
Raises NO_MODIFICATION_ALLOWED error.
removeNamedItem(
  String namespaceURI,
  String localname)

Raises NO_MODIFICATION_ALLOWED error.

NodeList

The NodeList is an iterator that has the following additional properties.

Properties Description
length
Number of nodes in the list.
item(Number index)
Get the item at the index place (first, second, and so on).

Value Object

Value is an object class that wraps MarkLogic XQuery types, enabling you to pass these objects into functions that are designed for those types.

Value supports valueOf and toObject methods for converting the underlying value to its closest native JavaScript value or object. For more details, see Value in the MarkLogic Server-Side JavaScript Function Reference.

Any builtin function whose signature indicates an XML atomic return type such as xs.date, xs.int, or xs.string returns a Value object. A function whose signature indicates a native JavaScript type such as number, boolean, or string returns a simple, native value.

For example, the fn.currentDate builtin function returns a Value representing an xs:date, and its return type in the MarkLogic Server-Side JavaScript Function Reference is xs.date. It returns a Value object that contains an XQuery xs:date value. This enables you to pass the result to date-specific functions such as xdmp.weekFromDate.

Similarly, lexicon functions such as cts.values, cts.words, and cts.geospatialBoxes return a Sequence of Value objects rather than native JavaScript objects in order to preserve type and support passing the Sequence items to cts.frequency.

See the following topics for more details:

Example: xs:date as Value

JavaScript has no native equivalent to xs:date. Such values can only be represented natively as a string, which loses the dateness of the value. The string has to be parsed back into a date before you can use it as input to a function that expects an xs:date:

xdmp.daynameFromDate(xs.date('1997-07-20'));

A DateTime function such as fn.currentDate returns a Value object representing an XQuery xs:date value. The following test returns true:

fn.currentDate() instanceof Value

The Value returned by fn.currentDate can be passed directly into functions that expect an xs.date, such as xdmp.daynameFromDate without conversion from a string:

xdmp.daynameFromDate(fn.currentDate());

If you probe the value returned by fn.currentDate, you can see it is not a native JavaScript type:

typeof fn.currentDate();                           // object
Object.prototype.toString.call(fn.currentDate());  // [object xs.date]

For more details about dates, see Dates in Server-Side JavaScript.

Comparison to Native JavaScript Values

You can use a Value like a native JavaScript value in contexts in which loose equality is sufficient. For example, when comparing a Value to a number using the == operator:

someDecimalValue == 1

You cannot successfully compare a Value to a native JavaScript value in contexts where strict equality or same value equality is used, such as the === operator, Array.prototype.indexOf, or Array.prototype.includes.

For more details, see Example: Comparison between a Value and a Number.

Example: Comparison between a Value and a Number

Suppose you call cts.values on a lexicon over xs:int values. The return value will be a Sequence containing Value objects that represent integer values. Supposed the first item in the returned Sequence contains a Value object equivalent to the number 10. Then following expressions evaluate to the results shown:

const mlValues = cts.values(cts.pathReference('/my/int/property'));

fn.head(mlValues) == 10;             // true
fn.head(mlValues) === 10;            // false
fn.head(mlValues).valueOf() === 10;  // true
mlValues.toArray().includes(10);     // false
mlValues.toArray().indexOf(10);      // -1 (no match)
fn.head(mlValues) instanceof Value;  // true
typeof fn.head(mlValues);            // 'object'
typeof fn.head(mlValues).valueOf();  // 'number'

Accessing JSON Nodes

When you store JSON in a MarkLogic database, it is stored as a document node with a JSON node child. You can access JSON documents stored in the database with fn.doc, or with any other function that returns a document. You have direct read-only access to the JSON nodes through the native JavaScript properties, including get a named property, querying for the existence of a named property, and enumerate all available named properties.

If you want to convert a JavaScript object to a JSON node, you can call xdmp.toJson on the JavaScript object and it will return a JSON node.

For more details about JSON nodes and documents, see Working With JSON in the Application Developer's Guide.

Sequence

A Sequence is a JavaScript Iterable object that represents a set of values. Many MarkLogic functions that return multiple values do so in Server-Side JavaScript by returning a Sequence. An iterable is a JavaScript object which returns an iterator object from the @@iterator method.

You can iterate over the values in a Sequence using a for..of loop. For example:

for (const doc of fn.collection('/my/coll')) {
  // do something with doc
}

If you want to extract just the first (or only) item in a Sequence without iteration, use fn.head. For example, the xdmp.unquote function returns a Sequence, but in many cases it is a Sequence containing only one item, so you could extract that single result with code like the following:

const node = fn.head(xdmp.unquote('<data>some xml</data>'))

You can create your own Sequence object from an array, an array-like, or another iterable using Sequence.from. For example, the following code snippet creates a Sequence from an array:

const mySeq = Sequence.from([1,2,3,4]);

Use fn.count to count the number of items in a Sequence. For example:

const mySeq = Sequence.from([1,2,3,4]);
fn.count(mySeq);       // returns 4

For more details, see Sequence Object in the MarkLogic Server-Side JavaScript Function Reference.

ValueIterator

This interface is deprecated. As of MarkLogic 9, no MarkLogic functions return a ValueIterator or accept a ValueIterator as input. Use the guidelines in this section to transition your code to Sequence.

Code that manipulates ValueIterator results as described in the following table will continue to work transparently when the return type is Sequence.

Guideline Do Do Not
Only use a for...of loop to iterate over the values in a ValueIterator returned by MarkLogic. Do not program directly to the underlying Iterator interface
const uris = cts.uris('/');
for (const u of uris) {
  // do something with u
}
const uris = cts.uris('/');
uris.next.value();
uris.next.value();
...
Use fn.head to access the first item in a ValueIterator, rather than using the pattern results.next().value.
fn.head(
  cts.uris('/')
);
cts.uris('/').next().value
Use fn.count to count the number of items in a ValueIterator object, rather than the count property.
fn.count(
  cts.uris('/')
);
cts.uris('/').count

Code that depends on the ValueIterator properties and methods next, count, and clone cannot used with a Sequence value.

You can use the instanceof operator to create code that behaves differently, depending on whether you are working with a ValueIterator or a Sequence. No MarkLogic 8 functions will return a Sequence, so you can be certain that code will not execute in MarkLogic 8.

For example, the following code uses ValueIterator.clone to preserve a set of values across iteration in MarkLogic 8, but skips the unnecessary cloning when the result type becomes Sequence.

const results = cts.uris('/', ['limit=10']);
const clone = {};
if (uris instanceof ValueIterator) {
  // iterator destructive, so clone to preserve orig
  clone = results.clone();
} else if (results instanceof Sequence) {
  // iteration is not destructive, no clone needed
  clone = results;
}
for (const val of clone) {
  // do something with val
}

JavaScript instanceof Operator

The JavaScript instanceof operator is available to test MarkLogic types (in addition to JavaScript types). For example, the following returns true:

const a = Sequence.from(["saab", "alfa romeo", "tesla"]);
a instanceof Sequence;
// returns true

Similarly, the following are some other examples of using instaceof with MarkLogic and JavaScript object types.

An xs.date object type:

const a = fn.currentDate();
a instanceof xs.date;
// returns true

Not an xs.date object type:

const a = fn.currentDate().toObject();
a instanceof xs.date;
// returns false

A JavaScript Date object type:

const a = fn.currentDate().toObject();
a instanceof Date;
// returns true

You can test for any of the following MarkLogic object types using instanceof:

  • Value (all MarkLogic Object types are subtypes of Value)
  • xs.anyAtomicType
  • cts.query (and all of its subtypes--the subtypes are also instance of cts.query)
  • ArrayNode
  • BinaryNode
  • BooleanNode
  • ObjectNode
  • XMLNode
  • Document
  • Node
  • NodeBuilder
  • Attr
  • CharacterData
  • Comment
  • Sequence
  • Text
  • Element
  • ProcessingInstruction
  • XMLDocument
  • ValueIterator

The following is an example using an XML document:

// assume "/one.xml" has content <name>value</name>
const a = fn.head(fn.doc("/one.xml")).root;
const b = fn.head(a.xpath("./text()"));
b instanceof Text;
// returns true

The following is an example using a JSON document:

// Assume "/car.json" has the content:
// {"car":"The fast electric car drove down the highway."}
const res = new Array();
const a = fn.head(fn.doc("/car.json"));
res.push(a instanceof Document);
const b = a.root;
res.push(b instanceof ObjectNode);
res;
// returns [true, true]

Similarly, you can test for any XML type. Note that the XML types in JavaScript have a dot (.) instead of a colon (:) between the namespace and the type name. For example, xs.integer, xs.string, and so on.

JavaScript Error API

When errors and exceptions are thrown in a Server-Side JavaScript program, a stack is thrown and can be caught using a standard JavaScript try/catch block. For details about each individual error message, see the Messages and Codes Reference Guide. This section includes the following parts:

JavaScript Error Properties and Functions

The following is the API available to JavaScript exceptions.

Properties/Functions Description
code
A string representing the code number.Only available for DOM errors, where the number is the DOM error code.
data
An array of strings containing the data thrown with the error.
message
The Error message string.
name
The error code string.
retryable
A boolean indicating if the error is retryable.
stack
The JavaScript stack. If the error is thrown from XQuery, the stack contains the concatenated stack from both XQuery and JavaScript.
stackFrame
An array of stack frames. See the stackFrame table below for details. For details, see JavaScript stackFrame Properties.
toString()
A formatted error message populated with data.

JavaScript stackFrame Properties

The following is the API available to each stackFrame:

Properties Description
line
The line number of the current frame.
column
The column number starting the current frame.
operation
The function name or operation of the current frame.
uri
The name of the resource that contains the script for the function/operation of this frame, or if the script name is undefined and its source ends with //# sourceURL=...Ķ string or deprecated //@ sourceURL=...Ķ string..
language
The query language of the current frame.
isEval
Was the associated function compiled from a call to eval. (JavaScript only)
variables
An array of (name, value) objects containing the variable bindings in a frame. Undefined if no variable bindings are available. (XQuery only)
contextItem
Context item in the frame. Undefined if no context item is available. (XQuery only)
contextPosition
Context position in the frame. Undefined if no context item is available. (XQuery only)

JavaScript try/catch Example

The following is a simple JavaScript try/catch example:

try{ xdmp.documentInsert("/foo.json", {"foo": "bar"} ); }
catch (err) { err.toString(); }

=> catches the following error 
( because it is missing the declareUpdate() call )
XDMP-UPDATEFUNCTIONFROMQUERY: xdmp:eval("// query&#10;
  try{ xdmp.documentInsert(&quot;/foo.json&quot;, {&q...", ()) 
  -- Cannot apply an update function from a query

JavaScript console Object

MarkLogic implements a console object, which contains functions to do things that log output to ErrorLog.txt in the MarkLogic data directory. The following are the console functions:

JavaScript Duration and Date Arithmetic and Comparison Methods

XQuery has operators that allow you to perform date math on duration typed data to do things like subtract durations to return dateTime values. In Server-Side JavaScript, you can get data returned in the various dateTime duration types and use the duration methods to add, subtract, multiply, divide and compare those durations. This section describes these duration arithmetic and comparison methods and includes the following parts:

Arithmetic Methods on Durations

Arithmetic methods are available on the following duration objects:

xs.yearMonthDuration Methods

The JavaScript object that is an instance of xs.yearMonthDuration is analogous to and has the same lexical representation to the XQuery xs:yearMonthDuration type, as described http://www.w3.org/TR/xpath-functions/#dt-yearMonthDuration. The following methods are available on xs.yearMonthDuration objects:

Method Description
add(xs.yearMonthDuration)
Adds two xs.yearMonthDuration values. Returns an xs.yearMonthDuration.
subtract(xs.yearMonthDuration)
Subtracts one xs.yearMonthDuration value from another. Returns an xs.yearMonthDuration.
multiply(Number)
Multiplies one xs.yearMonthDuration value by a Number. Returns an xs.yearMonthDuration.
divide(Number)
Divides an xs.yearMonthDuration by a Number. Returns an xs.yearMonthDuration.
divide(xs.yearMonthDuration)
Divides an xs.yearMonthDuration by an xs.yearMonthDuration. Returns a Number.

The following are some simple examples using these methods:

const v1 = xs.yearMonthDuration("P3Y7M");
const v2 = xs.yearMonthDuration("P1Y4M");

const r = {
"v1 + v2" : v1.add(v2),
"v1 - v2" : v1.subtract(v2),
"v1 * 2" : v1.multiply(2),
"v1 / 2" : v1.divide(2),
"v1 / v2" : v1.divide(v2)
};
r;

/*
returns:
{"v1 + v2":"P4Y11M", 
 "v1 - v2":"P2Y3M", 
 "v1 * 2":"P7Y2M", 
 "v1 / 2":"P1Y10M", 
 "v1 / v2":2.6875}
*/
xs.dayTimeDuration Methods

The JavaScript object that is an instance of xs.dayTimeDuration is analogous to and has the same lexical representation to the XQuery xs:dayTimeDuration type, as described http://www.w3.org/TR/xpath-functions/#dt-dayTimeDuration. The following methods are available on xs.dayTimeDuration objects:

Method Description
add(xs.dayTimeDuration)
Adds two xs.dayTimeDuration values. Returns an xs.dayTimeDuration.
subtract(xs.dayTimeDuration)
Subtracts one xs.dayTimeDuration value from another. Returns an xs.dayTimeDuration.
multiply(Number)
Multiplies one xs.dayTimeDuration value by a Number. Returns an xs.dayTimeDuration.
divide(Number)
Divides an xs.dayTimeDuration by a Number. Returns an xs.dayTimeDuration.
divide(xs.dayTimeDuration)
Divides an xs.dayTimeDuration by an xs.dayTimeDuration. Returns a Number.

The following are some simple examples using these methods:

const v1 = xs.dayTimeDuration("P5DT4H");
const v2 = xs.dayTimeDuration("P1DT1H");

const r = {
"v1 + v2" : v1.add(v2),
"v1 - v2" : v1.subtract(v2),
"v1 * 2" : v1.multiply(2),
"v1 / 2" : v1.divide(2),
"v1 / v2" : v1.divide(v2)
};
r;

/*
returns:
{"v1 + v2":"P6DT5H", 
 "v1 - v2":"P4DT3H", 
 "v1 * 2":"P10DT8H", 
 "v1 / 2":"P2DT14H", 
 "v1 / v2":4.96}
*/

Arithmetic Methods on Duration, Dates, and Times

Methods are available on the following duration, date, and dateTime objects:

xs.dateTime Methods

The following methods are available on xs.dateTime objects:

Method Description
add(xs.dayTimeDuration)
Returns the xs.dateTime value representing the end of the time period by adding an xs.dayTimeDuration to the xs.dateTime value that starts the period. Returns an xs.dateTime.
add(xs.yearMonthDuration)
Returns the xs.dateTime value representing the end of the time period by adding an xs.yearMonthDuration to the xs.dateTime value that starts the period. Returns an xs.dateTime.
subtract(xs.dateTime)
Returns the difference between two xs.dateTime values as an xs.dayTimeDuration.
subtract(xs.dayTimeDuration)
Returns the xs.dateTime value representing the beginning of the time period by subtracting an xs.yearMonthDuration from the xs.dateTime value that ends the period. Returns an xs.dateTime.
subtract(xs.dayTimeDuration)
Returns the xs.dateTime value representing the beginning of the time period by subtracting an xs.dayTimeDuration from the xs.dateTime value that ends the period. Returns an xs.dateTime.

The following are some simple examples using these methods:

const v1 = xs.dateTime(xs.date('2013-08-15'), xs.time('12:30:45-05:00'))
const v2 = xs.dateTime(xs.date('2012-04-01'), xs.time('01:10:25-02:00'))
const v3 = xs.yearMonthDuration("P3Y3M")
const v4 = xs.dayTimeDuration("PT1H")

const r = {
"v1 + v3" : v1.add(v3),
"v1 + v4" : v1.add(v4),
"v1 - v2" : v1.subtract(v2),
"v1 - v3" : v1.subtract(v3),
"v1 - v4" : v1.subtract(v4)
};
r;

/*
returns:
{"v1 + v3":"2016-11-15T12:30:45-05:00", 
 "v1 + v4":"2013-08-15T13:30:45-05:00", 
 "v1 - v2":"P501DT14H20M20S", 
 "v1 - v3":"2010-05-15T12:30:45-05:00", 
 "v1 - v4":"2013-08-15T11:30:45-05:00"}
*/
xs.date Methods

The following methods are available on xs.date objects:

Method Description
add(xs.dayTimeDuration)
Returns the xs.date value representing the end of the time period by adding an xs.dayTimeDuration to the xs.date value that starts the period. Returns an xs.date.
add(xs.yearMonthDuration)
Returns the xs.date value representing the end of the time period by adding an xs.yearMonthDuration to the xs.date value that starts the period. Returns an xs.date.
subtract(xs.date)
Returns the difference between two xs.date values as an xs.dayTimeDuration.
subtract(xs.dayTimeDuration)
Returns the xs.date value representing the beginning of the time period by subtracting an xs.yearMonthDuration from the xs.date value that ends the period. Returns an xs.date.
subtract(xs.dayTimeDuration)
Returns the xs.date value representing the beginning of the time period by subtracting an xs.dayTimeDuration from the xs.date value that ends the period. Returns an xs.date.

The following are some simple examples using these methods:

const v1 = xs.date('2013-08-15')
const v2 = xs.date('2012-04-01')
const v3 = xs.yearMonthDuration("P3Y3M")
const v4 = xs.dayTimeDuration("P1DT3H")

const r = {
"v1 + v3" : v1.add(v3),
"v1 + v4" : v1.add(v4),
"v1 - v2" : v1.subtract(v2),
"v1 - v3" : v1.subtract(v3),
"v1 - v4" : v1.subtract(v4)
};
r;

/*
returns:
{"v1 + v3":"2016-11-15", 
 "v1 + v4":"2013-08-16", 
 "v1 - v2":"P501D", 
 "v1 - v3":"2010-05-15", 
 "v1 - v4":"2013-08-13"}
*/
xs.time Methods

The following methods are available on xs.time objects:

Method Description
add(xs.dayTimeDuration)
Adds the value of the hours, minutes, and seconds components of an xs.dayTimeDuration to an xs.time value. Returns an xs.time.
subtract(xs.time)
Returns the difference between two xs.time values as an xs.dayTimeDuration.
subtract(xs.dayTimeDuration)
Subtracts the value of the hours, minutes, and seconds components of an xs.dayTimeDuration from an xs.time value. Returns an xs.time.

The following are some simple examples using these methods:

const v1 = xs.time('12:30:45-05:00')
const v2 = xs.time('01:10:25-02:00')
const v3 = xs.dayTimeDuration("PT1H")

const r = {
"v1 + v3" : v1.add(v3),
"v1 - v2" : v1.subtract(v2),
"v1 - v3" : v1.subtract(v3)
};
r;

/*
returns:
{"v1 + v3":"13:30:45-05:00", 
 "v1 - v2":"PT14H20M20S", 
 "v1 - v3":"11:30:45-05:00"}
*/

Comparison Methods on Duration, Date, and Time Values

Comparison methods are available to compare values (less than, greater than, and so on) on the following duration, date, and dateTime objects:

xs.yearMonthDuration Comparison Methods

The following comparison methods are available on xs.yearMonthDuration objects:

Method Description
lt(xs.yearMonthDuration)
Less than comparison on xs.yearMonthDuration values. Returns a Boolean.
le(xs.yearMonthDuration)
Less than or equal to comparison on xs.yearMonthDuration values. Returns a Boolean.
gt(xs.yearMonthDuration)
Greater than comparison on xs.yearMonthDuration values. Returns a Boolean.
ge(xs.yearMonthDuration)
Greater than or equal to comparison on xs.yearMonthDuration values. Returns a Boolean.
eq(xs.yearMonthDuration)
Equality comparison on xs.yearMonthDuration values. Returns a Boolean.
ne(xs.yearMonthDuration)
Not equal to comparison on xs.yearMonthDuration values. Returns a Boolean.

The following are some simple examples using these methods:

const v1 = xs.yearMonthDuration("P3Y7M");
const v2 = xs.yearMonthDuration("P1Y4M");

const r = {
"v1 lt v2" : v1.lt(v2),
"v1 le v2" : v1.le(v2),
"v1 gt v2" : v1.gt(v2),
"v1 ge v2" : v1.ge(v2),
"v1 eq v2" : v1.eq(v2),
"v1 ne v2" : v1.ne(v2)
};
r;

/*
returns:
{"v1 lt v2":false, 
 "v1 le v2":false, 
 "v1 gt v2":true, 
 "v1 ge v2":true, 
 "v1 eq v2":false, 
 "v1 ne v2":true}
*/
xs.dayTimeDuration Comparison Methods

The following comparison methods are available on xs.dayTimeDuration objects:

Method Description
lt(xs.dayTimeDuration)
Less than comparison on xs.dayTimeDuration values. Returns a Boolean.
le(xs.dayTimeDuration)
Less than or equal to comparison on xs.dayTimeDuration values. Returns a Boolean.
gt(xs.dayTimeDuration)
Greater than comparison on xs.dayTimeDuration values. Returns a Boolean.
ge(xs.dayTimeDuration)
Greater than or equal to comparison on xs.dayTimeDuration values. Returns a Boolean.
eq(xs.dayTimeDuration)
Equality comparison on xs.dayTimeDuration values. Returns a Boolean.
ne(xs.dayTimeDuration)
Not equal to comparison on xs.dayTimeDuration values. Returns a Boolean.

The following are some simple examples using these methods:

const v1 = xs.dayTimeDuration("P5DT4H");
const v2 = xs.dayTimeDuration("P1DT1H");

const r = {
"v1 lt v2" : v1.lt(v2),
"v1 le v2" : v1.le(v2),
"v1 gt v2" : v1.gt(v2),
"v1 ge v2" : v1.ge(v2),
"v1 eq v2" : v1.eq(v2),
"v1 ne v2" : v1.ne(v2)
};
r;

/*
returns:
{"v1 lt v2":false, 
 "v1 le v2":false, 
 "v1 gt v2":true, 
 "v1 ge v2":true, 
 "v1 eq v2":false, 
 "v1 ne v2":true}
*/
xs.dateTime Comparison Methods

The following comparison methods are available on xs.dateTime objects:

Method Description
lt(xs.dateTime)
Less than comparison on xs.dateTime values. Returns a Boolean.
le(xs.dateTime)
Less than or equal to comparison on xs.dateTime values. Returns a Boolean.
gt(xs.dateTime)
Greater than comparison on xs.dateTime values. Returns a Boolean.
ge(xs.dateTime)
Greater than or equal to comparison on xs.dateTime values. Returns a Boolean.
eq(xs.dateTime)
Equality comparison on xs.dateTime values. Returns a Boolean.
ne(xs.dateTime)
Not equal to comparison on xs.dateTime values. Returns a Boolean.

The following are some simple examples using these methods:

const v1 = xs.dateTime(xs.date('2013-08-15'), xs.time('12:30:45-05:00'))
const v2 = xs.dateTime(xs.date('2012-04-01'), xs.time('01:10:25-02:00'))

const r = {
"v1 lt v2" : v1.lt(v2),
"v1 le v2" : v1.le(v2),
"v1 gt v2" : v1.gt(v2),
"v1 ge v2" : v1.ge(v2),
"v1 eq v2" : v1.eq(v2),
"v1 ne v2" : v1.ne(v2)
};
r;

/*
returns:
{"v1 lt v2":false, 
 "v1 le v2":false, 
 "v1 gt v2":true, 
 "v1 ge v2":true, 
 "v1 eq v2":false, 
 "v1 ne v2":true}
*/
xs.date Comparison Methods

The following comparison methods are available on xs.date objects:

Method Description
lt(xs.date)
Less than comparison on xs.date values. Returns a Boolean.
le(xs.date)
Less than or equal to comparison on xs.date values. Returns a Boolean.
gt(xs.date)
Greater than comparison on xs.date values. Returns a Boolean.
ge(xs.date)
Greater than or equal to comparison on xs.date values. Returns a Boolean.
eq(xs.date)
Equality comparison on xs.date values. Returns a Boolean.
ne(xs.date)
Not equal to comparison on xs.date values. Returns a Boolean.

The following are some simple examples using these methods:

const v1 = xs.date('2013-08-15');
const v2 = xs.date('2012-04-01');

const r = {
"v1 lt v2" : v1.lt(v2),
"v1 le v2" : v1.le(v2),
"v1 gt v2" : v1.gt(v2),
"v1 ge v2" : v1.ge(v2),
"v1 eq v2" : v1.eq(v2),
"v1 ne v2" : v1.ne(v2)
};
r;

/*
returns:
{"v1 lt v2":false, 
 "v1 le v2":false, 
 "v1 gt v2":true, 
 "v1 ge v2":true, 
 "v1 eq v2":false, 
 "v1 ne v2":true}
*/
xs.time Comparison Methods

The following comparison methods are available on xs.time objects:

Method Description
lt(xs.time)
Less than comparison on xs.time values. Returns a Boolean.
le(xs.time)
Less than or equal to comparison on xs.time values. Returns a Boolean.
gt(xs.time)
Greater than comparison on xs.time values. Returns a Boolean.
ge(xs.time)
Greater than or equal to comparison on xs.time values. Returns a Boolean.
eq(xs.time)
Equality comparison on xs.time values. Returns a Boolean.
ne(xs.time)
Not equal to comparison on xs.time values. Returns a Boolean.

The following are some simple examples using these methods:

const v1 = xs.time('12:30:45-05:00');
const v2 = xs.time('01:10:25-02:00');

const r = {
"v1 lt v2" : v1.lt(v2),
"v1 le v2" : v1.le(v2),
"v1 gt v2" : v1.gt(v2),
"v1 ge v2" : v1.ge(v2),
"v1 eq v2" : v1.eq(v2),
"v1 ne v2" : v1.ne(v2)
};
r;

/*
returns:
{"v1 lt v2":false, 
 "v1 le v2":false, 
 "v1 gt v2":true, 
 "v1 ge v2":true, 
 "v1 eq v2":false, 
 "v1 ne v2":true}
*/
xs.gYearMonth Comparison Methods

The following comparison methods are available on xs.gYearMonth objects:

Method Description
eq(xs.gYearMonth)
Equality comparison on xs.gYearMonth values. Returns a Boolean.
ne(xs.gYearMonth)
Not equal to comparison on xs.gYearMonth values. Returns a Boolean.

The following are some simple examples using these methods:

const v1 = xs.gYearMonth('2013-08');
const v2 = xs.gYearMonth('2012-04');

const r = {
"v1 eq v2" : v1.eq(v2),
"v1 ne v2" : v1.ne(v2)
};
r;

/*
returns:
{"v1 eq v2":false, 
 "v1 ne v2":true}
*/
xs.gYear Comparison Methods

The following comparison methods are available on xs.gYear objects:

Method Description
eq(xs.gYear)
Equality comparison on xs.gYear values. Returns a Boolean.
ne(xs.gYear)
Not equal to comparison on xs.gYear values. Returns a Boolean.

The following are some simple examples using these methods:

const v1 = xs.gYear('2013');
const v2 = xs.gYear('2012');

const r = {
"v1 eq v2" : v1.eq(v2),
"v1 ne v2" : v1.ne(v2)
};
r;

/*
returns:
{"v1 eq v2":false, 
 "v1 ne v2":true}
*/
xs.gMonthDay Comparison Methods

The following comparison methods are available on xs.gMonthDay objects:

Method Description
eq(xs.xs.gMonthDay)
Equality comparison on xs.xs.gMonthDay values. Returns a Boolean.
ne(xs.xs.gMonthDay)
Not equal to comparison on xs.xs.gMonthDay values. Returns a Boolean.

The following are some simple examples using these methods:

const v1 = xs.gMonthDay('--08-20');
const v2 = xs.gMonthDay('--04-14');

const r = {
"v1 eq v2" : v1.eq(v2),
"v1 ne v2" : v1.ne(v2)
};
r;

/*
returns:
{"v1 eq v2":false, 
 "v1 ne v2":true}
*/
xs.gMonth Comparison Methods

The following comparison methods are available on xs.gMonth objects:

Method Description
eq(xs.gMonth)
Equality comparison on xs.gMonth values. Returns a Boolean.
ne(xs.gMonth)
Not equal to comparison on xs.gMonth values. Returns a Boolean.

The following are some simple examples using these methods:

const v1 = xs.gMonth('--08');
const v2 = xs.gMonth('--04');

const r = {
"v1 eq v2" : v1.eq(v2),
"v1 ne v2" : v1.ne(v2)
};
r;

/*
returns:
{"v1 eq v2":false, 
 "v1 ne v2":true}
*/
xs.gDay Comparison Methods

The following comparison methods are available on xs.gDay objects:

Method Description
eq(xs.gDay)
Equality comparison on xs.gDay values. Returns a Boolean.
ne(xs.gDay)
Not equal to comparison on xs.gDay values. Returns a Boolean.

The following are some simple examples using these methods:

const v1 = xs.gDay('---08');
const v2 = xs.gDay('---04');

const r = {
"v1 eq v2" : v1.eq(v2),
"v1 ne v2" : v1.ne(v2)
};
r;

/*
returns:
{"v1 eq v2":false, 
 "v1 ne v2":true}
*/

MarkLogic JavaScript Functions

There are a large number of MarkLogic built-in functions available in JavaScript. In general, most functions available in XQuery have siblings that are available in JavaScript. For details on the MarkLogic functions available in JavaScript, see JavaScript Functions and Constructors.

« Previous chapter
Next chapter »