SXP stands for Simple XML Persistence, and is a quick-and-dirty C++
library I threw together. It provides a simple (I hope) mechanism for
enabling the objects in your application to persist themselves (i.e.
read from and write to) to a XML file. It is built as a C++ wrapper
around James Clark's excellent expat parser.

SXP's major selling points are:

ease of use: a major design goal for it was adding XML
persistence to a class to take around 2 line of code per class
member (one for reading and one for writing). Efficiency concerns
and C++ syntax quirks expanded this number to around 4 lines of code
per class member (plus some fixed overhead); still, you should be
able to add XML persistence to your classes in a minutes, rather
than hours.

efficiency: XML persistence via SXP adds to your persistable
objects four virtual functions and no data members. If you need to
support persisting of object references, you might need to add a
single pointer to your objects. SXP can be used directly with all
but the most lightweight of objects. SXP uses hash tables and works
with one string compare ( strcmp() ) per XML tag in the
input file. SXP reuses its internal objects from a pool to avoid
constant allocation/deallocation of small objects.

acceptable performance: SXP is more than fast enough for
prototyping applications and even for small-to-medium
production-level projects.

If you are allergic towards industry buzzwords (like myself), you
probably think XML is for consultants and "enterprise developers"
(whatever that means), not for Real Programmers (like yourself).
Still, I think XML is a Good Thing (TM), and is suitable not only for
some multi-million dollar project with 5000 pages of design documents
filled with UML and Booch notation, but also for the config files of
your little pet project you're developing in your spare time, or for
the document format of the application you're working on to in your
[non-spare?!?] time. Here are a few reasons why I like XML:

XML files are easy to view and easy to edit with a simple text
editor - anything from Notepad to emacs will do. There are also
several freely available XML editors, which make the task even
easier - check out the "Buyer's Guide" section at XML.com. This means it will be easier to debug
your save/load code. Ever had the problem when you write your save
and load routines, and saving and loading a file definitely doesn't
produce the same memory objects you started with? You have no idea
whether the bug is in the save or the load routine, and spend 1 hour
tracing the correct one. Not with XML: one look at the XML file
itself can tell you if it's correct.

XML files are open - anyone can read your XML files, process
them, convert them with a XML parser or a few lines of Perl code.
(If you still haven't picked up Perl, go ahead and spend 2-3 days to
learn it. You'll thank me.) That "anyone" includes yourself after
six months - if you're like me, after 6 months you won't know
anything about the code you're happily hacking at today, including
how to read its data files. You can find XML parsers for all kinds
of environments and programming languages.

XML files are high-level - the parser and the support lib
(something like SXP) will take care of handling primitive data types
like numbers and strings, and you'll never have the joy again of
having to store the string length before the string itself (brrr...)
Still, XML files are more compact than most high-level alternatives
(I've used MS OLE IPropertyBags, stored in OLE structured storage
files, which definitely incur more overhead).

Disk space is ultra-cheap today, so the overhead of XML compared
to binary files can be safely ignored in most cases. (In the rest of
the cases, you're looking at more data than you can handle without a
database engine.)

XML is simple to use. The special case of using XML for object
persistence is made even more simple with SXP.

SXP was developed on Win32 with Visual C++ 6.0 and tested with expat 1.95.1. It uses
heavily STL for strings and collections. If you have expat and STL on
your system, you should be able to compile and use SXP - but I haven't
really tried it. There are reports of using expat on the Mac and
on Linux.

SXP is meant for fast prototyping; it was easy to write, and it is
easy to use. Its performance isn't what it would be if I didn't take
the easy shortcut with STL strings and lists. If you decide to use SXP
in a production-level application, you should probably rip off STL and
replace it with your own custom string and list handling in static
arrays. Quick profiling has shown that when handling large
multimegabyte XML files SXP spends about 30% of its time in
expat, 55-60% in the STL support routines and only 10-15% in the
SXP code itself. Moral: you can get it to run much, much faster, if
you need.

Still, SXP is not too slow to be unusable: for example, reading a 5
MB XML file describing the structure of a graph with 1000 nodes and
100 000 connections between them (see the second example below) takes
less then 4 seconds on my 450 MHz Celeron. This comes to show that,
first, with today's CPUs you can get away with being lazy and using
STL, and, second, expat is a darn good parser.

config.cpp,
config.xml - a simple example of using SXP to store
configuration information (or user preferences, if you like) in an
XML file.

graph.cpp,
graph.xml - a bit more complicated example of using SXP to store
a more complex data structure (a graph), illustrates a possible
technique for persisting object references.

expat, sadly, has become more difficult to built lately.
What I did with SXP 1.1 was get the expat 1.95.1 archive, open the DSP
in the /lib folder, compile the Debug version, compile the Release version,
find/fix two small annoying bugs in it, rebuild again and copy the following files
over to the folder where SXP is buing built:expat.lib, expat.h, expat.dll

You will have to redistribute expat.dll
with your application if you use SXP, or you can compile
and link expat directly with your software (which is a better solution
IMHO).

Two stupid bugs fixed related to UTF-8 support, more code moved from
the header to the CPP, and changed to compile against newest expat version.

1.0

SXP is stable at this point; slight derivations have been successfully
used in two projects, and it seems it serves its purposes well. I feel
it deserves 1.0 status now.

Removed the autoconf madness, which confused a lot of people.

Fixed a horrendous stupidity on my part which lead to steady
memory leaking and mayhem.

Introduced more-or-less decent error handling - reporting of
expat errors together with row/column in the XML where the error
occurred.

0.061

Cleaned up incompatibilities with GCC, GNU autoconf support
courtesy of Andrei Errapart. You can choose from three
versions now: The basic version, guaranteed to work on Win32/MSVC++
and linux/GCC, the TGZ version with all the GNU autoconf machinery
inside it for all the others, and a RPM for Linux/IA-32.

0.06

Unicode output/input via UTF-8 (only for character data, tags
and attribute names can be ASCII IMHO).

0.05

All in all, from a user class point of view, only one thing has
changed: recursive invocation when outputting XML is done with
WriteSubElement, not with WriteElement.

reading of simple data types from char * and fprintf-ing of said
data types in FP segregated into separate classes and into a new
file; this provides a single place to add data converters

hashtable moved to singleton object instead of all-static class
because of problems with order of construction of global objects
(more specifically, tags which are static members in user
classes)

Both sxp.h itself and the samples (config.cpp and graph.cpp) are
very heavily commented and will serve the role of a manual.
Please first read config.cpp, then the
comments for the interfaces in sxp.h. Once you
understand that, read graph.cpp. This should
be more than enough for you to know how to SXP-enable your own
classes. If you think more explanation and instruction is needed, write me and I'll try to
find the time for a decent manual.

I will try to find some time for a decent introduction text.
Any suggestions
towards more functionality? I'm trying to adhere to the KISS principle
in SXP, though; I don't want to fill it with bells and whistles.

Basically, I believe SXP is done, useful and elegantly minimalistic
in its present form; don't expect great deeds.

Some things I won't do in SXP:

streams - IMO streams are less convenient than the printf
mumbo-jumbo - once you're used to it.

"portability" - I won't pollute SXP with thousands of
#define's to make it compileable on retarded compilers. If your
compiler doesn't have namespaces, get a better compiler, or do
a find&replace for SXP:: - no one has to suffer ifdefs because
of you.

rewrite it without STL for "speed" - STL strings are
fast enough for me, thank you very much; if you have huge
attribute lists, you might substitute maps with hash_maps.

SXP has not been extensively tested. It worked on all the test
examples I wrote, a modification of it works inside a commercial
application I'm working on, but I can't guarantee it will work for
you. If it crashes your system, deletes or corrupts your data, and
destroys your personal life, it's not my fault - you've been warned.
Proceed at your own risk.

SXP can be distributed by any of the non-viral public licenses out
there. I like the Artistic
License; I don't like the GPL. Basically, do whatever you like
with it, let me know if you make it better, and don't put it under the
GPL. If you badly need it under the GPL (evil! evil!), please contact
me and we'll arrange something (e.g. an exception just for your
project).