Calling Functions

The syntax of a function call, shown in Figure 8-1, is the same whether it is a built-in function or a user-defined function. It is the qualified name of the function, followed by a parenthesized list of the arguments, separated by commas.[*] For example, to call the substring function, you might use:

substring($prodName, 1, 5)
Syntax of a function call

Figure 8-1. Syntax of a function call

Function calls can be included anywhere an expression is permitted. For example, you might include a function call in a let clause, as in:

let $name := substring($prodName, 1, 5)

or in element constructor content:

<name>{substring($prodName, 1, 5)}</name>

or in the predicate of a path expression:

doc("catalog.xml")/catalog/product[substring(name, 1, 5) = 'Short']

Function Names

Functions have namespace-qualified names. All of the built-in function names are in the XPath Functions Namespace, http://www.w3.org/2005/xpath-functions. Since this is the default namespace for functions, the built-in functions can be referenced without a namespace prefix (unless you have overridden the default function namespace, which is not recommended). Some XQuery users still prefer to use the fn prefix for these functions, but this is normally unnecessary.

If the function is user-defined, it must be called by its prefixed name. If a function is declared in the same query module, you can call it using the same prefixed name found in the declaration. Some functions may use the local prefix, a built-in prefix for locally declared functions. To call these functions, you use the local prefix in the name, as in:

declare function local:return2 ( ) as xs:integer {2};
<size>{local:return2( )}</size>

If the function is in a separate query module, it has a different namespace that needs to be declared. For example, if you are calling a function named discountPrice in the namespace http://datypic.com/prod, you must declare that namespace and use the appropriate prefix when calling the function, as in:

import module namespace prod = "http://datypic.com/prod"
                     at "http://datypic.com/prod/module.xq";
<price>{prod:discountPrice( )}</price>

Function Signatures

A function signature is used to describe the inputs and outputs of a function. For example, the signature of the built-in upper-case function is:

upper-case($arg as xs:string?) as xs:string

The signature indicates:

  • The name of the function, in this case, upper-case.

  • The list of parameters. In this case, there is only one, whose name is $arg and whose type is xs:string?. The question mark after xs:string indicates that the function accepts a single xs:string value or the empty sequence.

  • The return type of the function, in this case, xs:string.

There may be several signatures associated with the same function name, with a different number of parameters. For example, there are two signatures for the substring function:

substring($sourceString as xs:string?,
          $startingLoc as xs:double) as xs:string
substring($sourceString as xs:string?,
          $startingLoc as xs:double,
          $length as xs:double) as xs:string

The second signature has one additional parameter, $length.

Argument Lists

When calling a function, there must be an argument for every parameter specified in the function signature. If there is more than one signature, as in the case of the substring function, the argument list may match either function signature. If the function does not take any arguments, the parentheses are still required, although there is nothing between them, as in:

current-date( )

You are not limited to simple variable names and literals in a function call. You can have complex, nested expressions that are evaluated before evaluation of the function. For example, the following function call has one argument that is itself a function call, and another argument that is a parenthesized conditional (if) expression:

concat(substring($name,1,$sublen), (if ($addT) then "T" else ""))

Calling a function never changes the value of any of the variables that are passed to it. In the preceding example, the value of $name does not change during evaluation of the substring function.

Argument lists and the empty sequence

Passing the empty sequence or a zero-length string for an argument is not the same as omitting an argument. For example:

substring($myString, 2)

is not the same as:

substring($myString, 2, ( ))

The first function call matches the first signature of substring, and therefore returns a substring of $myString starting at position 2. The second matches the second signature of substring, which takes three arguments. This function call raises a type error because the third argument of the substring function must be an xs:double value, and cannot be the empty sequence.

Conversely, if an argument can be the empty sequence, this does not mean it can be omitted. For example, the upper-case function expects one argument, which can be the empty sequence. It is not acceptable to use upper-case( ), although it is acceptable to use upper-case(( )), because the inner parentheses (( )) represent the empty sequence.

Argument lists and sequences

The syntax of an argument list is similar to the syntax of a sequence constructor, and it is important not to confuse the two. Each expression in the argument list (separated by a comma) is considered a single argument. A sequence passed to a function is considered a single argument, not a list of arguments. Some functions expect sequences as arguments. For example, the max function, whose signature is:

max($arg as xs:anyAtomicType*) as xs:anyAtomicType?

expects one argument that is a sequence. Therefore, an appropriate call to max is:

max ((1, 2, 3))

not:

max (1, 2, 3)

which is attempting to pass it three arguments.

Conversely, it is not acceptable to pass a sequence to a function that expects several arguments that are atomic values. For example, in:

substring( ($myString, 2) )

the argument list contains only one argument, which happens to be a sequence of two items, because of the extra parentheses. This raises an error because the function expects two (or three) arguments.

You may want to pass a sequence of multiple items to a function to apply the function to each of those items. For example, to take the substring of each of the product names, you might be tempted to write:

substring( doc("catalog.xml")//name, 1, 3)

but this won't work because the first argument of substring is not allowed to contain more than one item. Instead, you could use a path expression, as in:

doc("catalog.xml")//name/substring( ., 1, 3 )

which will return a sequence of four strings: Fle, Flo, Del, and Cot.

Sequence Types

The types of parameters are expressed as sequence types, which specify both the number and type (and/or node kind) of items that make up the parameter. The most commonly used sequence types are the name of a specific atomic type, such as xs:integer, xs:double, xs:date, or xs:string. The sequence type xs:anyAtomicType, which matches any atomic value, can also be specified. Some of the built-in functions also use numeric to allow values of any numeric type.

Occurrence indicators are used to indicate how many items can be in a sequence. The occurrence indicators are:

? For zero or one items

* For zero, one, or many items

+ For one or many items

If no occurrence indicator is specified, it is assumed that it means one and only one. For example, a sequence type of xs:integer matches one and only one atomic value of type xs:integer. A sequence type of xs:string* matches a sequence that is either the empty sequence, or contains one or more atomic values of type xs:string. Sequence types are covered in detail in "Sequence Types" in Chapter 11.

Remember that there is no difference between an item, and a sequence that contains only that item. If a function expects xs:string* (a sequence of zero to many strings), it is perfectly acceptable to pass it a single string such as "xyz".

When you call a function, sometimes the type of an argument differs from the type specified in the function signature. For example, you may pass an xs:integer to a function that expects an xs:decimal. Alternatively, you may pass an element that contains a string to a function that expects just the string itself. XQuery defines rules, known as function conversion rules, for converting arguments to the expected type. The function conversion rules are covered in detail in "Function Conversion Rules" in Chapter 11.

Not all arguments can be converted using the function conversion rules, because function conversion does not involve straight casting from one type to another. For example, you cannot pass a string to a function that expects an integer. If you attempt to pass an argument that does not match the sequence type specified in the function signature, a type error is raised.



[*] An argument is the actual value that is passed to a function, while a parameter is its definition.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.17.174.204