The new website for MarkLogic is www.progress.com/marklogic. Visit it.
BLOG ARTICLE

Comparison Operators in XQuery: What’s the difference between “eq” and “=”?

Back to blog
03.30.2012
3 minute read
Back to blog
03.30.2012
3 minute read

One common XQuery-related question that frequently comes up for developers is why do XQuery and XSLT have more than one operator for each comparison? The table below shows that there are twelve rather than six comparison operators, half of which use letters (such as eq) and half of which use symbols (such as =):

Value Comparison General Comparison
equals eq =
not equals ne !=
less than lt <
greater than gt >
less than or equal to le <=
greater than or equal to ge >=

In the 1.0-ml version of XQuery, there’s no difference in behavior by default; eq behaves the same as =, etc. If you want to dig a little deeper, this is because of function mapping, which you have the ability to enable or disable; if you disable function mapping, eq will not behave the same as =.

However, whereas they behave the same in 1.0-ml, they actually mean different things. The value comparison operators (eqlt, etc.) are designed for comparing single values (i.e., sequences of one value each). The general comparison operators (=<, etc.) are designed for comparing sequences of more than one value.

How can I put this to practice?

In the standard 1.0 version of XQuery (which MarkLogic also supports), you’ll get an error if you try to use a value comparison operator to compare sequences of more than one value:

xquery version "1.0";
"foo" eq ("foo","bar")

Here’s the error that results:

XQuery error using eq

The 1.0-ml implementation relaxes this restriction, hence the effectively identical behavior of eq and =, etc. In XQuery version 1.0, you’d instead need to use a general comparison operator (=):

"foo" = ("foo","bar")

Using the general comparison operator will return true in both versions 1.0 and 1.0-ml and the expression will return true if any of the items on the left compare successfully with any of the items on the right. This is sometimes called “existential quantification.” A longer, more explicit way to write this in XQuery would be to use a “some” expression:

some $item1 in "foo", $item2 in ("foo","bar") satisfies $item1 eq $item2

You may have a policy (and I think it’s generally a good one) of always writing your code in version 1.0-ml, so does it even matter that you know this difference?

I think so. Knowing the difference enables you to write code that is not only more interoperable, but more expressive of your intentions:

  • You may want to write an XQuery 1.0 library that works across multiple implementations
  • You may want to better understand the code that’s written in XQuery 1.0 libraries that you use
  • You may not want to depend on a XQuery 1.0-ml-specific error fallback behavior
  • You may want to more clearly express your intentions in your choice of which operator to use

For example, if you know that $var will contain at most one number, and you want to compare it with a literal number, it’s best to use the value comparison operator, such as le:

$var le 5

Using <= would imply that $var may contain more than one number. On the other hand, if $var suddenly has more than one value, you’d want to use <= instead (to avoid an error in version 1.0), if in fact that’s your intention (i.e. return true if any of $var are less than or equal to the given number):

(: Are any of the numbers in $var less than or equal to 5? :)
$var <= 5

Walk through an example

Bringing this to a more practical example, say you have a <person> element in your XML and you want to find the person named “Bill”:

//person[name eq "Bill"]

If you know that a <person> will only ever have one <name>, then the above code is safe. But if you’re using 1.0 and one of your <person> elements has more than one <name>, then this will throw an error. If you’d rather find the <person> element that has any child <name> with a value of “Bill”, then the = operator will work the way you want (in both versions 1.0 and 1.0-ml):

//person[name = "Bill"]

To conclude, I’ll add one historical note. Before XPath 2.0 (which is what XQuery uses), there were no value comparison operators; eqgtlt, and the like, simply didn’t exist. You only had =, >, <, etc. in XSLT/XPath 1.0. With XPath 2.0, XSLT 2.0, and XQuery, you now have a choice.

Additional Resources

Read more about Function Mapping in 1.0-ml to better understand why these operators behave the same way.

Share this article

Read More

Related Posts

Like what you just read, here are a few more articles for you to check out or you can visit our blog overview page to see more.

Tutorial

Poker Fun with XQuery

In this post, we dive into building a full five-card draw poker game with a configurable number of players. Written in XQuery 1.0, along with MarkLogic extensions to the language, this game provides examples of some great programming capabilities, including usage of maps, recursions, random numbers, and side effects. Hopefully, we will show those new to XQuery a look at the language that they may not get to see in other tutorials or examples.

All Blog Articles
Tutorial

Protecting passwords in ml-gradle projects

If you are getting involved in a project using ml-gradle, this tip should come in handy if you are not allowed to put passwords (especially the admin password!) in plain text. Without this restriction, you may have multiple passwords in your gradle.properties file if there are multiple MarkLogic users that you need to configure. Instead of storing these passwords in gradle.properties, you can retrieve them from a location where they’re encrypted using a Gradle credentials plugin.

All Blog Articles
Tutorial

Getting Started with Apache Nifi: Migrating from Relational to MarkLogic

Apache NiFi introduces a code-free approach of migrating content directly from a relational database system into MarkLogic. Here we walk you through getting started with migrating data from a relational database into MarkLogic

All Blog Articles

Sign up for a Demo

Don’t waste time stitching together components. MarkLogic combines the power of a multi-model database, search, and semantic AI technology in a single platform with mastering, metadata management, government-grade security and more.

Request a Demo