General Links
SDS Homepage
 
General Documentation
Main index
Copyright notices
What is SDS
Installing SDS
SDS HowTo
Using SDS
Language frontends
FAQ
Plans/further releases
 
Developer Documentation
Architecture description
Developer How-To
XML-system for classes
CSF Specification
CSF DTD Documentation
SDOC Info
Develop code in Lisp
 
Email page maintainer
stig@ii.uib.no
 
Hosted at

SF project page

  

XML-System

Why?

XML is the core of SDS, and SDS currently use four XML formats to represent information. A framework for making it easy to utilise XML is then necessary. Such a framework has been built which takes care of (but might be extended):

  • reading and parsing xml-files
  • building trees of the various elements of the xml data
  • making it easy to access and update the trees
  • allow easy building of such trees from other sources
  • dump such trees to a new xml-file which might be parsed again

This functionality is split into two parts: an xml-module and a API-generator. The xml-module provides the raw functionality needed to work with xml, ie reading and dumping. The API-generator reads a specification and generates the correct classes and the glue code between the generated classes and the xml-module. Both the xml-module and the generated api is specific for a language, e.g C++, but the specification is used for all languages. This means that the same API is available in all languages which the XML-system has been ported to, currently C++, Java and Common Lisp. This saves a lot of work and maintenance and makes it trivial to create a new dataformat in XML which is instantly usable in several languages. To prove the point, the API-specifications are in XML and the API-generator's API is of course created by the API-generator (ie a bootstrap).

More on the APIs

The apis directory contains specifications for the various APIs which use the XML-system. An API is common in several languages and should be specified here and not be hand-written. Adding support for new languages is not too difficult, and examples for C++, Java and Common Lisp exist. The API-Generator will generate only the front-end and simple code for using the xml-system. The actual functionality of your tool must still be written :-)

C++ xml-system

  • include/abstract.H - Has the ABC XML_Parseable which has to be the parent of any XML-"serializable" class. Just as important is the XML_Factory class which must be subclassed for your dtd/"domain" (e.g CSF, Prefs) and used with XML_Tool.
  • include/xml/tools.H - Most communication when dumping and reading xml will go through this class.
  • include/xml/infotype.H - The classes here are simple wrappers of information which should be set to the attrInfo and subelemInfo members in XML_Parseable.

I guess that currently only the PTR_TO macro is useful for a "normal" developer. Use it as in normal code, e.g src/csf/class.cpp. Only if you decide to hack xmltool.cpp you should check out the other macros. Use the macros when setting and getting variables to let xmltool.cpp survive when stuff is changed. The system used is particularly nasty and may not work on all compilers.

And remember:

  • Good examples of more or less complex classes which are mapped to one or more elements are found in the csf and prefs directories. Both these directories have their own factories and small testprograms to show how they're utilised from above.
  • If you want the data from a XML_ParseablePtr you should use the get() function to get a pointer which you can cast to the appropriate type. If it's a multi-type list, you should do a conditional on getElementName(). The whole system is what it is because of C++'s fascist typing. Compare it with the Lisp-code...
  • The XML behaviour can be overrided, and sometimes this is necessary. A special case which is supported by XML_Parseable::printAsXML is when several subelemInfos point to the same memory-area. The system then assumes that you only want the content in that list (usually is a list) listed once and not once for every subelement registered to that memory location. Check the CSF_API class which maps several elements to the same list but where content is only printed once. A very hackish special case, but is very useful in SDOC.
  • All XML_Parseable derived classes which can be instantiated needs a copy() function. Usually this returns a new version of the class, using the copy-constructor and should be trivial to add. REMEMBER that the XML_ParseablePtr is a wrapped pointer (Ptr_Wrap) which takes care of calling copy() so you don't really need to mess with an assignment-operator and a copy-constructor, and destructors become trivial as the XML_ParseablePtr cleans up after itself. The pointer-wrapping saves a lot of code and complexity in most classes, and basically all the complexity is reduced to xmltool.cpp and functions which manipulate pointers. Macros will probably show up soon.
  • The XML_Parseable class will take care of deleting attrInfo and subelemInfo. Actually Sarray does this by itself..

CL/CLOS xml-system

Most of the CLOS system for XML seems to be working quite well and uses more or less the same naming and classes as the C++ code. Most of what is said above also applies to the CLOS implementation, except for the XML_ParseablePtr which isn't needed (lists are used all over the place to save space). It has however gone through some lispification (use of '-' instead of '_' in names and constants have been put in +..+). Heavier use of neat macros were inevitable and reduces the code size to 1/4 of the equivalent c++ code.