OpenVPMS supports the XPath 1.0 functions and operators to perform expression evaluation within archetypes, macros, and reports.

By far the most commonly function is concat, used to concatenate strings.  Hence concat('ab','34','ef') yields 'ab34ef'.

However, others are used. One terrifyingly complex example is that used to generate the customer's name.  It is as follows:

concat(/details/companyName,substring(concat(/details/lastName,',',/details/firstName),0,number(not(/details/companyName))*string-length(concat(/details/lastName,',',/details/firstName))+1)) 

This returns the companyName if there is one, else lastName,firstName. It relies on the concatenation of two mutually exclusive strings, the first one being empty if the condition is false, the second one being empty if the condition is true. This is called "Becker's method", attributed to Oliver Becker.

In the above you can see the functions concat, substring, number, not, string-length, and the operators * and + being used.

Note also that using the jxpath function expr:ifempty() function provides a far simpler version of the above, for example:

expr:ifempty(openvpms:get(.,'product.entity.printedName'), openvpms:get(.,'product.entity.name'))

The table below shows the available functions. (Others are defined but are not relevant to our use.)

Note that except for sum() which returns a BigDecimal, all the functions that return a number (eg ceiling(), count() etc) return a Double. This can be ignored except when you use the functions in JasperReports. So the field [count(list:distinct(., "items.target.patient.entity.id"))] must be typed as  java.lang.Double .

Also, the arguments cannot be JasperReports fields, but must be jxpath functions. Hence
   [concat(product.entity.printedName,... ] will not work, but
   [concat(openvpms:get(., 'product.entity.printedName'), .... ] will

boolean(e) Converts object e to Boolean type. False values include numeric zero, empty strings, and empty node sets; other values are considered true.
ceiling(e) Returns the integer closest to infinity that is less than or equal to e. Examples: ceiling(5.9) returns 6; ceiling(-5.9) returns -5.
concat(e1, e2, ...) Concatenates the string values of its arguments and returns the result as a single string.
contains(s1, s2) True if string s1 contains s2.
count(c) Returns the number of nodes in the collection c as returned by some of the list: functions. Example:
  count(list:distinct(., "items.target.patient.entity.id"))
false() Returns the Boolean “false” value.
floor(e) Returns the integer closest to minus infinity that is greater than or equal to e. Examples: floor(5.9) returns 5; floor(-5.9) returns -6.
normalize-space(s) Returns the string s, except that all leading and trailing whitespace are removed, and all internal clumps of whitespace are replaced by single spaces. Note that a newline character counts as a whitespace character.
not(e) Returns the Boolean complement of the truth value of expression e: true if e is false, false if it is true.
number(e) Converts an expression e to a number. If e is not a valid number, you get the special numeric value NaN (not a number). If e is a Boolean value, you get 1 for true and 0 for false.
round(e) Returns the integer closest to the value of expression e. Values with a fractional part of 0.5 are rounded towards infinity. Examples: round(5.1) returns 5; round(5.5) returns 6; and round(-5.5) returns -5.
starts-with(s1, s2) True if string s1 starts with string s2.
string(e) Converts e to a string.
string-length(s) Returns the length of string s.
substring(s, n1, n2) Returns a substring of s starting at position n1 (counting from 1), and ending n2 characters later, or at the end of the string, whichever comes first. You can omit the third argument, and it will return the substring starting at position n1 and going through the end of s. For example, "substring('abcdefgh', 3, 4)" returns "cdef".
substring-after(s1, s2) If s2 is a substring of s1, returns the part of s1 after the first occurrence of s2; otherwise it returns the empty string.
substring-before(s1, s2) If s2 is a substring of s1, returns the part of s1 before the first occurrence of s2; otherwise it returns the empty string.
sum(c) Returns the sum, for each node collectionc, of the result of converting the string-values of the node to a number.
translate(s1, s2, s3) The result is a copy of string s1 with each occurrence of a character from string s2 replaced with the corresponding character from string s3. If s3 is shorter than s2, this function will delete from its result any characters from s2 that don't correspond to characters in s3
eg translate(s1, '
', '') will strip any newline charcters from s1
and
translate(s1, '
', ' ') will translate any newline charcters to spaces
true() Returns the Boolean “true” value.

 

Below are the operators used in XPath expressions. In the table below, e stands for any XPath expression.

e1+e2 If e1and e2are numbers, their sum.
e1-e2 e1minus e2.
e1*e2 The product of e1and e2.
e1 div e2 If e1and e2are numbers, their quotient as a floating-point value.
e1 mod e2 The floating-point remainder of e1divided by e2.
e1 = e2 Tests to see if e1equals e2.
e1 &lt; e2 Tests to see if e1is less than e2. You can't say e1< e2inside an attribute: the less-than sign must be escaped as "&lt;".
e1 &lt;= e2 Tests to see if e1is less than or equal to e2.
e1 &gt; e2 Tests for greater-than.
e1 &gt;= e2 Tests for greater or equal.
e1 != e2 Tests for inequality.
e1 and e2 True if both e1and e2are true. If e1is false, e2is not evaluated.
e1 or e2 True if either e1or e2is true. If e1is true, e2is not evaluated.
/e Evaluate estarting at the document node. For example, "/barge"selects the <barge>element that is the child of the document node.
e1/e2 The /operator separates levels in a tree. For example, "/barge/load"selects all <load>children of the <barge>element child of the document node.
//e Abbreviation for descendant-or-self::e.
./e Abbreviation for self::e.
../e Abbreviation for parent::e.
@e Abbreviation for attribute::e.
e1|e2 Selects the union of nodes that match e1and those that match e2.
* A wild-card operator; matches all nodes of the proper type for the context. For example, "*"selects all child elements of the context node, and "feet/@*"selects all attributes of the context node's <feet>children.
e1[e2] Square brackets enclose a predicate, which specifies an expression e2that selects nodes from a larger set e1.For example, in the XPath expression "para[@class='note']", the paraselects all <para>children of the context node, and then the predicate selects only the children that have an attribute class="note". Another example: "item[1]"would select the first <item>child of the context node.
$e The dollar sign indicates that the following name is a variable name. For example, in an XSLT script, if variable n is set to 357, <xsl:value-of select="$n"/>is expanded to the string "357".
Syndicate content