Relational eXpression Map (rxm) is a terse database- and output-agnostic query language for generating structured documents.


The software requirements include:

  • Java 8 - Development environment
  • Gradle - Automated build process

Quick Start

Download, compile, build, and parse the example using:

git clone https://bitbucket.org/djarvis/rxm.git
gradle -Dbeautify=true clean build javadoc run -Pargs=test/people.rxm


This section describes how to invoke the Java API to generate documents.


Generate an XML document using rxm. For example:

import com.whitemagicsoftware.rxm.RXM;

public class QueryTest {
  public static void main( String args[] ) throws Exception {
    RXM rxm = new RXM(
      "root   > people," +
      "person > person," +

    System.out.println( rxm.toString( getConnection() ) );


A module is a set of rxm expressions that can be reused. For example:

import com.whitemagicsoftware.rxm.RXM;

public class QueryTest {
  public static void main( String args[] ) throws Exception {
    RXM rxm = new RXM(
      "module person," +
      "person > person," +

    rxm.add( "root > people, import person," );

    System.out.println( rxm.toString( getConnection(), "json" ) );


This section describes the rxm syntax, which involves:

  • a Map;
  • a Where clause;
  • namespace definitions; and
  • module definitions.


An example map resembles:

root               > people,           # "root" keyword starts the document
person             > person,           # maps table context to a node
.age               > @age,             # @ maps a column to an attribute node
.first_name        > name/first,       # maps a column to a node
.last_name         > .../last,         # ... reuses the previous node's path
account.person_id +> person.person_id, # +> performs an INNER JOIN
account            > account,          # context is now "account" node
.id                > @id,              # account id attribute
^,                                     # pop stack to previous table context
address            > address,          # switch context to "address" node
.*,                                    # glob remaining columns
;                                      # Denotes optional WHERE clause

The example mapping produces:

  <person age="42">
    <account id="123"/>
      <street>123 Query Lane</street>
      <city>San Francisco</city>

Any structured document format can be produced, including JSON.


Stack pops (^) switch context to a previous element. Multiple consecutive pop lines are permitted; extraneous pops are silently ignored: context never traverses beyond the root node.


A column demarcation followed by a Kleene star (.*) maps remaining columns automatically. Each node name corresponds directly to the entity column name.


Example rxm expressions for SQL WHERE clauses include:

account.id  = :id      # : starts a named parameter
account.id <> :id      # inequality parameter comparison
account.id  = {:id, 1} # becomes IN set
account.id <> {:id, 1} # becomes NOT IN set
account.id  = null     # becomes IS NULL
account.id <> null     # becomes IS NOT NULL
account.id  = 'text'   # string equality comparison
account.id  = -42      # numeric equality comparison
account.id  < 42       # numeric less than comparison
account.id  > 42       # numeric greater than comparison
account.id <= 42       # numeric less than or equal to comparison
account.id >= 42       # numeric greater than or equal to comparison

Additionally, the && and || tokens perform logical and and or operations, respectively.


Namespace syntax resembles:

root       > people(html, http://www.w3.org/TR/html4/),
person     > html:person,
person.id  > people:id( people, http://www.people.com ),


Modules are defined using the module keyword. For example:

module person,
person             > person,
.first_name        > first,
.last_name         > name/last,
.age               > @age,

Modules are referenced using the import keyword. For example:

root               > people,
import person,
address            > address,

Modules may not contain a root element.


The reasons for rxm include:

  • Eliminate repetitious code.
  • Decouple SQL statements from document output format.
  • Few databases are fully compliant with SQL/XML:2006.
  • Provide a database-agnostic mechanism to generate structured documents.
  • XQuery has limited open-source implementations for major RDBMS software.


Review the JDBC documentation to understand how database connections are established.