Visit our project page on sourceforge (http://sourceforge.net/projects/ptdom)
The Purple Tree DOM C++ Library (ptdom) aims to provide a C++ interface to DOM/XML C-libraries. A major design goal of the library is to do this without a C++ object library. It attempts to do this by providing header files that contain template classes. These templates use a "traits" mechanism to access the functions of the C-library in the templated class. The is sometimes called the "Bridge Pattern". The design of the templates incorporates the following objectives:
This goal is that once this library is installed and can be accessed using a standard #include directive no Purple Tree C++ library needs to be included. The current version of ptdom needs no object library other than the XML C-library. Currently the only library targeted is the libxml2 library.
Why not use a C++ object library? A drawback of using such a library is that there is not yet a standard for C++ object files. Therefore a library must usually be compiled by the same compiler as the program. This means that you cannot distribute the library already compiled, have to distribute the library as a set of compiler-specific libraries or you force the programmer to use a specific compiler. I felt this was unacceptable in a shared library particularly when this limitation does not exist for shared C libraries. And I feel the lack of a standard for C++ object files has been a major drawback for the language.
To use the DOM interface include the header for the
library you wish to use. Currently the only one available is for
libxml2
and is called xml2_dom
.
#include <xml2_dom>
using purpletree;
dom::document my_doc = dom::implementation::deserialise ("my_file.xml");
// my_doc cannot be null.
...
This program can be compiled with commands like.
make `xml2-config --cflags` -c somefile.cc
make -o applname somefile.o `xml2-config --libs`
Somewhat implicit in the specification is that the document object owns all of its nodes. Most C-libraries use this model with users required to explicitly delete a document. This is not appropriate for C++ where memory management should be automatic. The solution we have currently implemented involves a reference count of the document object that causes the document to be deleted when the reference count goes to zero. This means that a document object will continue to exist as long as the program has any sub-node, not just the document node, in scope. For example the following code, although somewhat bizarre, will work.
#include <xml2_dom>
using purpletree;
dom::element
get_doc_element (const std::string& a_filename)
{
dom::document l_doc = dom::implementation::deserialise (a_filename);
// my_doc cannot be null as a bad read results in an exception
return l_doc.document_element();
}
The DOM Core 1 specification uses a null node as the return value of a number of methods to indicate various conditions. This library always returns a constructed object that is not a NULL value in the traditional C/C++ sense. To supports this null value concept a test method is_null() is used instead of a convert-to-bool or compare-to-NULL operation. This design decision is based on (1) the difficulty of providing the other two operations in an unambiguous and "meaningful" way and (2) using the method makes a statement such as
if (a_node.is_null ()) ...
unambigous while holding to the spirit of the DOM Core 1. A null node can be created in client code using the default constructor.
The current library does not enforce a dom_string to be
UTF16. Instead it uses the character size native to the C-library. Use
the get_utf8/16
, set_utf8/16
methods to
translate C++ std::strings
(assumed to be utf8) and
std::wstrings
(assumed to be utf16) to and from
dom_strings.
Another addition to the DOM Core 1 string manipulation is the
provision of s_validate_name
. This method can ensure that
a dom_string is a valid DOM name.
The one interface not fully specified by the dom Core 1 was the Implementation. This was intentional on the part of the designers as they felt that this was an area where there would be most variation depending on the platform and implementation. In addition to the specified method, this tempate library provides methods for the creation, serialisation and validation of dom object trees.