14. Jess and XML
14.1. Introduction
Jess now supports an XML-based rule language. Rather than adopting an evolving standard like RuleML, Jess's XML rule language (JessML) was designed to be close in structure to the Jess language itself. JessML is a hybrid imperative/declarative language, just like the Jess language itself. That means you can not only write rules in it, but define and call functions as well. Anything you can do in the Jess language, you can do in JessML too.
Transformation between JessML and RuleML and other XML rule languages should be simple using XSLT, and in fact we hope to provide several such translators with the final Jess 7 release.
JessML code is quite verbose. Remember, though, that's it's intended to be easy for machines, not humans, to work with.
14.2. The JessML Language
14.2.1. The rulebase Element
The top-level element in an executable JessML file is the rulebase element. A rulebase element can contain any other JessML elements in any order.14.2.2. Names
Many constructs -- rules, templates, modules, functions -- have a name. In JessML, names are represented by a name tag. A name tag contains the text of the name, optionally including a module name:- PLANNING::store-plan-data
- MAIN::animal
- make-pair
14.2.3. Values
Just as in Jess, simple data items in JessML are called values. A JessML value consists of a type element and the data itself. The type element's body can contain one of the type names in the jess.RU class. Here are a few examples of valid values:- <value><type>SYMBOL</type>nil</value>
- <value><type>INTEGER</type>1</value>
- <value><type>STRING</type>A String</value>
14.2.4. Function calls
The actions of rules, some of their tests and the bodies of deffunctions are made up of funcalls, short for "function calls." A JessML funcall tag contains a name element and a series of value elements as the arguments. The Jess function call "(+ ?x 1)" looks like this in JessML:<funcall> <name> + </name> <value><type>VARIABLE</type>x</value> <value><type>INTEGER</type>1</value> </funcall>
14.2.4.1. Special functions
A few special functions have slightly different syntax. The modify and duplicate functions each accept a single value plus one or more slot elements as arguments, while the assert function accepts one or more fact elements.14.2.5. Slots
A slot in JessML is just the same as it is in Jess: it's a list (usually a two-element list, but sometimes longer) with a symbol as the head. In JessML, a slot element always starts with a name element, and contains one or more value elements; for example,<slot> <name> location </name> <value><type>SYMBOL</type>nil</value> </slot>
14.2.6. Templates
You can define a template in the JessML language using the template element. A template element contains a name element followed by any number of elements. The value elements of the slots are interpreted as default values.
<template> <name> monkey </name> <slot> <name> species </name> <value> <type>SYMBOL</type> rhesus </value> </slot> </template>
You can also automatically define a template based on a Java class using a from-class property, like this:
<template> <name> MAIN::button </name> <properties> <property> <name>from-class</name> <value><type>SYMBOL</type>java.awt.Button</value></property> </properties> </template>
14.2.7. Rules
A rule contains a nameelement, a lhs element, and a rhs element. The rhs element contains a collection of funcall elements representing the rule's actions. The lhs element contains groups and patterns, which are somewhat complex, and will be discussed in the following sections. A simple rule might look like this (this rule prints "Fired!" for each "MAIN::button" fact that exists.
<rule> <name> MAIN::myrule </name> <lhs> <group> <name> and </name> <pattern> <name> MAIN::button </name> </pattern> </group> </lhs> <rhs> <funcall> <name> printout </name> <value><type>SYMBOL</type>t</value> <value><type>STRING</type>Fired!</value> <value><type>SYMBOL</type>crlf</value> </funcall> </rhs> </rule>
14.2.7.1. Groups
A group element represents one of Jess's grouping conditional elements: and, or, or not. Every rule has an "and" group enclosing all of its patterns, as in the example rule above. A group always contains a name element followed by any combination of nested groups or pattern elements.14.2.7.2. Patterns
A pattern element represents a single pattern in a rule. It consists of a name element, an optional binding element, and any number of slot elements. The values of the slots should consist of test elements (described below.)14.2.7.3. Pattern bindings
You can use a binding element to bind a variable to the fact that matches a pattern. The text of the binding element is simply the name of the variable to use.
14.2.7.4. Tests
A test element represents a single test in a pattern. A test can either be discriminating or nondiscriminating. A discriminating test is one that sometimes matches and sometimes doesn't. A nondiscriminating test is one that always matches; generally this refers to tests that merely bind a variable to the contents of a slot. There's no difference in the syntax between these two types of test.
A test element contains a type element, an optional conjunction element, and either a value element or a funcall element. The type element's body is either "eq" or "neq", corresponding to a positive or negative test. The conjunction element's body can be either "and" or "or", and it is can used only in the second and later tests on a slot. Finally, the value element represents the test itself. If it's a constant, the contents of the slot will be compared to it for equality or inequality, according to the contents of the type element. If the value is a variable, and if that variable has not been bound to a slot, the variable is bound to the current slot. Otherwise, the variable is compared to the contents of the slot. Finally, if there is a funcall element, the function is evaluated and the test passes if the result is true (for an "eq" test) or false (for a "neq" test.)
14.2.7.5. Facts
14.2.7.6. Deffacts
14.2.7.7. Modules
14.2.7.8. Globals
14.3. Writing Constructs in JessML
You can translate a file of Jess language code into XML using Jess's XMLPrinter tool; this is a good way to learn how Jess and JessML correspond. The command to use this tool looks like:
java -classpath jess.jar jess.xml.XMLPrinter myfile.clp > myfile.xml
The file "myfile.xml" will be a complete translation of all the code in "myfile.clp", including templates, rules, deffunctions, and top-level function calls.
14.4. Parsing JessML
In general, anywhere you can use a file full of Jess language code, you can also use a JessML file. For example, the file you provide as a command-line argument to jess.Main can be a JessML file.
The standard batch function can read JessML code as well as Jess language code. It decides what kind of file it is looking at by looking for the "<?xml" characters that should begin a well-formed XML file. require, which uses batch internally, will work with JessML as well.
You can get a little bit more control of the process by using the classes JessSAXParser or JessSAXHandler directly. JessSAXParser will parse a JessML document from an InputSource, installing the results into a Rete object you provide. JessSAXHandler is a SAX event handler that you can use with your own parser.