CookXml: A General Purpose XML Interpreter for Java



Support This Project


stats counter


Logo Logo IntelliJ IDEA


CookXml is a powerful general purpose dynamic XML data binding tool. It is designed to be easy to use and easily extensible. The current implementation only does the unmarshaling. The marshaling aspect will be added.

CookXml unmarshals objects from XML using an interpretation approach. It loads user defined tag libraries at runtime to convert XML documents into Java objects. The result is a highly configurable XML parser. Thus, it is not only great for XML data binding, it is also useful in creating parsers for scripts written in XML. In fact, I use this approach to create many small parsers at work.

CookXml uses a set of delegates which are creators (object factories), setters, adders, and converters, to interpret the XML. These delegates together forms a tag library.

To use CookXml, one usually creates a tag library which controls how objects are created, modified, and linked together. Objects are created using factory objects whenever a tag is encountered. Their properties are in turn set when an attribute is seen, usually through default setter functions. Objects can be added to their parent objects in prefix or postfix order. Most things can be done using default constructor for the object, variables/setter functions, and an add function. So it is simple to write a tag library.

CookXml is designed to be easily extensible. If you create a new Java class, say MySlider based on JSlider, which is already in CookSwing tag library, you can create the new tag <myslider> with much less effort, by telling Swing tag library that <myslider> inherits <slider>. Instantly, <myslider> inherits all the efforts you put in setting <slider>'s attributes (notably dozens of Swing listeners related attributes), adding children, etc (well, probably just one or two lines of code using CookXml anyways, but still you are worry free from implementation changes I would make toward <slider>.).

Although CookXml with certain tag libraries can be powerful enough to turn XML into a complete language that can do pretty much anything doable in Java, there is no point in doing so. My view on XML is that it serves as an excellent tool for headers, configuration files, XUL, communication protocols, and to some extent data storage. CookXml excels in dealing all these.

I use CookXml extensively for personal and work related projects. For 90% of XML related parsing (not including XUL), I found that using CookXml is faster/easier to write. For the rest 10%, mostly query results in XML which contain a lot of different ignored tags/fields, I found direct DOM tree parsing can be faster/simpler. Then again, maybe it is just me that I dislike having to learn dozens of different XML libraries for the very tiny fraction of features I would be interested in.

What's New

  1. CookXml 3.0.1
    • Fixed a bug that CookXml only taking SingleNSTagLibrary as the input parameter.
    • cookxml:tag now can now take ns:tag format as well. ns is the namespace prefix. Note that since DecodeEngine reads xmlns in order. So the prefix used before the actual xmlns setting will cause an error.
  2. CookXml 3.0
    • Added XML namespace support. CookXml now supports XML files with or without namespaces, or partially with namespaces.
    • Extracted out the reserved words (such as id, idref, setas, func, ctor, etc) to a standalone TagLibrary in namespace. CookXml Common tag library by default uses this tag library as its parent. CookSwing and CookSwt in turn uses CookXml Common tag library as their parents. This chain of tag libraries are necessary for backward compatiblity parsing XML files that do not have namespaces.
    • A MultiNSTagLibrary is create for easily bundling of several tag libraries that each is used for a different namespace.
  3. CookXml 2.5
    • added a feature that allows one to call CleanupHook objects after DecodeEngine is finished. This feature is used in CookSwing where label's labelfor attribute requires a forward lookup for ids/variables. A simple way of doing it is basically caching the demand and calling setLabelFor after DecodeEngine has finished parsing the XML.
    • added a global propertychangelistener attribute that allows one to add a PropertyChangeListener with a given property name in either propertychangelistener="variableName" or propertychangelistener="variableName,propertyName" format.
  4. CookXml 2.4.1
    • There were still some codes that use Class.forName in 2.4 instead of user defined ClassLoader. This update should change them all.
  5. CookXml 2.4
    • added setDefaultClassLoader and setClassLoader functions to CookXml to facilitate the resource locating. The tags that are affected are <include> and <text>.
      All sub-projects have been updated to utilize this feature. This feature is mainly useful for plugin based applications where plugins are loaded using non-system ClassLoader (e.g. URLClassLoader).
  6. CookXml 2.3.1
    • remove a debugging message that should have been commented out for accessing a field.
  7. CookXml 2.3
    • added the feature to read/write non-public (package, private, protected) variables. By default, this feature is disabled. Call CookXml.setDefaultAccessible (true) or within individual CookXml objects, call setAccessible (true). Note that this feature will generate a SecurityException if there is a SecurityManager (as in case of sandbox Java Web Start) and thus should only be used if you have pretty much full permission access.
      This feature is useful if you ever get annoyed by the number of public variables that show up in the public variable/function list of Eclipse/IntelliJ IDEA, this feature is useful hiding most of them. IntelliJ IDEA may consider some of those variables as unused though.
  8. CookXml 2.2
    • added idref and varref global attributes. The purpose is to replace <idref> and <varref> tags. Instead of using
       <varref ctor="myPanel" tag="panel"></varref>
      in XML, now you can just do
      <panel varref="myPanel"></panel>
      , which is much more intuitive and clear. <idref> and <varref> tags will continue to stay for people who find them shorter to type sometimes.
    • listeners can be added using variable reference or if it is the right type, it can be added directly. This allows listeners generated from script to be added via mechanism like setas="actionlistener".
  9. CookXml 2.1.1
    • fixed a bug in <object ctor="className"> introduced in CookXml 2.0. The className check part of the code could not be reached due to an unchecked exception.
  10. CookXml 2.1
    • idref tag now works for creators that use helper objects as well.
    • identified a potential place where an exception could be leaked w/o being wrapped with CookXmlException.
    • put NoCreatorException under CreatorException.
    • CallFunctionSetter now throws exception if parameters don't match rather than quit sliently.
    • added setProperty/getProperty functions to DecodeEngine so that it can act as a cache for individual creators.
  11. CookXml 2.0
    • Exception handling. It is now possible for user to intercept exceptions and make decisions to suppress it, allowing the decoder to continue to work on the rest of the XML, or generate an error, causing the decoder to immediately return with the error. Of course logging is very possible with this method.
    • Improved include.
    • fixed a bug in InheritableTagLibrary where some adders are not correctly called when parent tags are set up after child tags.
  12. CookXml 1.0
    The initial release

Sub Projects

  • CookSwing extends CookXml to provide a capability of generating Swing GUI from an XML document. Not only CookSwing demonstrates the prowess of CookXml, CookSwing itself is a very useful product to any Java GUI programmers who want to have an easily customizable GUI.
  • CookSwt is another library that provides the capability of generate SWT GUI from an XML document.

The fundamental goal of CookSwing and CookSwt is to provide specific supports for GUI packages and free up programmers from doing tedious GUI hard coding and cleanup the code, WITHOUT compromising functionality. Yet, it is different from XMLEncoder/Decoder provided by JDK, which is tedious/unreadable in XML. CookXml/CookSwing/CookSwt intend to provide powerful yet concise representation of GUI (or whatever objects) in XML.

I believe in writing a program that does well what it is supposed to do. I am not interested in a XUL that can be run anywhere; after all, Swing and SWT are portable themselves. If you are switching from Swing to SWT, or vice versa, tough luck with any XML toolkits. So, in the mean time, pick the one that provides the best use the GUI :)

Scripting Extensions

The following extensions adds scripting capability to CookXml.

(c) Copyright 2004-2007 Heng Yuan. All rights reserved.

Valid XHTML 1.0! Valid CSS!