XMLisp is the integration of Lisp with XML. The Lisp Meta Object Protocol is used to establish a simple and highly efficient mapping between CLOS objects and the XML extensible markup language. It is not just an API to read XML files and turn them into some Lisp flavored representation. Instead, it integrates Lisp and XML into one environment at two levels. At a language level it allows the arbitrary combination of Lisp expressions and XML elements. CLOS objects can be printed as XML elements. XML elements evaluate into CLOS objects. At a tool level XMLisp allows users to fluidly experiment with XML. Type XML elements into the lisp listener. Evaluate complete or parts of hierarchical XML elements. Inspect complex XML elements using the inspector. Get support from symbol completion when editing XML.

Papers

Repenning, A. and Ioannidou, A., X-expressions in XMLisp: S-expressions and Extensible Markup Language Unite, in Proceedings of the ACM SIGPLAN International Lisp Conference (ILC 2007), (Cambridge, England, 2007), ACM Press.

What's NEW?

2.0: replaced fake MOP with real MOP; portable loader, compilable sexp+XML files; early LispWorks version

2.0.1: work with OpenMCL, save-object method

2.0.2: SBCL patch; bufix: untyped numbers will be XML quoted again

2.1: CLISP support, (setf part-of) aggregator method

2.2: *xmlisp-packages* to control which packages use XMLisp reader

2.3: support namespaces as package prefix, e.g, <xml:bla ... /> , ACL support

XMLisp 2.3 (for MCL 5, 5.1, LispWorks 4.3, OpenMCL 0.13.2, SBCL, CLISP, ACL)

XMLisp 3.5.2, 12/16/08 optimized: Tree shacked, easy to load/port single file

XMLisp >= 3.6 now moved to http://code.google.com/p/xmlisp/

ToDos:

- implement tool integration for Windows, and Linux

 

To learn about XMLisp have a look at some simple examples:

;; Example 1: HTML Link
;; simple mapping between class/element and slot/attribute name
 
(defclass A (xml-serializer)
   ((href :accessor href :initform "" :initarg :href))
   (:documentation "HTML link"))
 
(inspect <a href="http://www.agentsheets.com"/>)
 <a href="http://www.agentsheets.com">AgentSheets</a>
 
;; Example 2: RSS
(defclass RSS (xml-serializer)
   ((version :accessor version :initform "")
   (channel :accessor channel :initform nil))
   (:documentation "RSS main element"))
(defclass CHANNEL (xml-serializer)
   ((title :accessor title :initform "")
   (link :accessor link :initform "")
   (description :accessor description :initform "")
   (image :accessor image :initform nil)
   (managingeditor :accessor managingeditor :initform "")
   (ttl :accessor ttl :initform nil :documentation "don't know what this is")
   (language :accessor language :initform "")
   (copyright :accessor copyright :initform "")
   (webmaster :accessor webMaster :initform "")
   (pubdate :accessor pubDate :initform "")
   (lastbuilddate :accessor lastBuildDate :initform "")
   (category :accessor category :initform "")
   (generator :accessor generator :initform "")
   (docs :accessor docs :initform "")
   (items :accessor items :initform nil :documentation "list of RSS item"))
   (:documentation "RSS channel"))
 
(defclass IMAGE (xml-serializer)
   ((title :accessor title :initform "")
   (url :accessor url :initform "")
   (link :accessor link :initform "")
   (width :accessor width :initform 0))
   (:documentation "RSS Image"))
 
(defclass ITEM (xml-serializer)
   ((title :accessor title :initform "")
   (link :accessor link :initform "")
   (description :accessor description :initform "")
   (pubdate :accessor pubdate :initform ""))
   (:documentation "RSS news Item"))
;; pick an XML RSS file from the examples/xml folder
;; if you pick other RSS files keep in mind that the above spec is incomplete
 
(defparameter *RSS-News* (load-object (ccl:choose-file-dialog)))
 
;; and walk throught the RSS structure
(inspect *RSS-News*)

;; Example 3: Typed Slots
;; Typed slots use the print-typed-attribute-value, read-typed-attribute-value, print-typed-subelement-value
;; CODECs 
(defclass COIN (xml-serializer)
   ((head-is-up :accessor head-is-up :type boolean)))
 
(inspect <coin head-is-up="true"/>)
 
;; Example 4: simple Aggregation: rule based Visual AgenTalk-like language 
   ;; use MOP name matching to implement aggregation
   ;; e.g. slot "RULES" will contain a list of "RULE" elements
(defclass COMMAND (xml-serializer)
   ((name :accessor name :initform "" :initarg :name)
   (comments :accessor comments :initform nil)))
 
(defclass BEHAVIOR (command)
   ((method-commands :accessor method-commands :initform nil)))
 
(defclass METHOD-COMMAND (command)
   ((trigger :accessor trigger :initform nil)
   (rules :accessor rules :initform nil)))
(defclass TRIGGER (command)
   ())
(defclass RULE (command)
   ((condition-commands :accessor condition-commands :initform nil :initarg :condition-commands)
   (action-commands :accessor action-commands :initform nil :initarg :action-commands)
   (is-enabled :accessor is-enabled :initform t :initarg :is-enabled :type boolean)
   (probablility :accessor probability :initform 0.9s0 :initarg :probability :type short-float)))
 
(defclass CONDITION-COMMAND (command)
   ())
 
(defclass ACTION-COMMAND (command)
   ())
 
(defclass TRIGGER (command)
   ())
 
(inspect
 <behavior name="random Move">
  <method-command name="mouse" trigger="on mouse down">
   <rule>
    <condition-command name="see_a"/>
    <condition-command name="key"/>
    <action-command name="play_sound"/>
   </rule>
  </method-command>
 </behavior> )
 
;; Example 5: User defined Aggregation
   ;; This is by no means a complete definition
 
(defclass HTML-BASE-CLASS (xml-serializer)
   ()
   (:documentation "mother of all HTML element classes"))
 
(defclass HTML (html-base-class)
   ((items :accessor items :initform nil))
   (:documentation "Contains all the html items of an HTML document"))
 
(defmethod ADD-SUBOBJECT ((Self html) (Item html-base-class))
   ;; extend this method to add all html-base-class instances to the "items" slot
   (add-object-to-slot Self Item 'items))
   
 
(defclass A (html-base-class)
   ((href :accessor href :initform "" :initarg :href))
   (:documentation "HTML link"))
 
(defclass FONT (html-base-class)
   ((face :accessor face)
   (size :accessor size :type number))
   (:documentation "Font info"))
 
 
(inspect
<HTML>
<font face="arial, sans-serif" size="-2">Small Text here</font>
 <font face="arial, sans-serif" size="+2">Large Text here</font>
 <a href="http://www.cs.colorado.edu">Go CU</a>
</HTML> )


Enabling/Disabling the XMLisp Reader

Use the *xmlisp-packages* variable to enable and disable the XMLisp reader. Examples:

(setq *xmlisp-packages* :all) ;; XMLisp XML reading will take place in ALL packages

(setq *xmlisp-packages* nil) ;; no XML reading in any package

(setq *xmlisp-packages* (list (find-package :cl-user) (find-package :xml))) ;; XML reading in :cl-user, :xml packages

 

 

This material is based in part upon work supported by the National Science Foundation under Grant Numbers NSF OII/ENG 0349663, and NSF ITR/PE 0205625. Any opinions, findings, and conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of the National Science Foundation.