more docu
This commit is contained in:
		
							
								
								
									
										21
									
								
								AUTHORS
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								AUTHORS
									
									
									
									
									
								
							| @@ -0,0 +1,21 @@ | ||||
| <address> | ||||
| 	<name> | ||||
| 		<first>Marc</first> | ||||
| 		<middle>Roman</middle> | ||||
| 		<last>Wäckerlin</last> | ||||
| 	</name> | ||||
| 	<location> | ||||
| 		<line>SwissSign AG</line> | ||||
| 		<line>Pfingstweidstrasse 60b</line> | ||||
| 		<line>8005 Zürich</line> | ||||
| 	</location> | ||||
| 	<country>Schweiz</country> | ||||
| 	<email>marc@waeckerlin.org</email> | ||||
| 	<email>marc.waeckerlin@swisssign.com</email> | ||||
| 	<url>http://dev.swisssign.com/trac/libxml-cxx</url> | ||||
| 	<url>http://marc.wäckerlin.ch</url> | ||||
| 	<url>http://marc.waeckerlin.org</url> | ||||
| 	<url>http://dev.swisssign.com</url> | ||||
| 	<url>http://swissign.com</url> | ||||
| 	<url>http://swissign.ch</url> | ||||
| </address> | ||||
|   | ||||
							
								
								
									
										22
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								README
									
									
									
									
									
								
							| @@ -0,0 +1,22 @@ | ||||
| This is a C++ class for reading and writing XML structures. | ||||
|  | ||||
| All informaton can be found in the generated doxygen project documentation. | ||||
|  | ||||
| Rationale: The initial idea was to map C++ data structures to XML | ||||
| files for configuration files that can easily be edited by hand. This | ||||
| library does not need any kind of C++ code parser or special pre | ||||
| compiler. You can specify a schema entirly in native C++. The schema | ||||
| is verified when XML is read and exceptions are thrown when the XML to | ||||
| be pares is invalid. Exceptions specify exactly the location and | ||||
| reason of the problem, so that the editor of the XML file can easily | ||||
| find and correct the problem. | ||||
|  | ||||
| (More rationale: See also "related Pages" in the doxygen project documentation) | ||||
|  | ||||
| Structure of the files: | ||||
|   src:          The source code of the library | ||||
|   doc/html:     Doxygen documentation oft the library usage | ||||
|   doc/examples: Example code (included in doxygen documentation) | ||||
|   test:         CppUnit test files - can also be taken as examples | ||||
|  | ||||
| Project URL: http://dev.swisssign.com | ||||
|   | ||||
							
								
								
									
										14
									
								
								configure.in
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								configure.in
									
									
									
									
									
								
							| @@ -12,7 +12,7 @@ AM_INIT_AUTOMAKE(x_packagename, x_major.x_minor.x_least, [marc@waeckerlin.org]) | ||||
|  | ||||
| # files to create | ||||
| AC_CONFIG_FILES(makefile | ||||
|                 src/makefile test/makefile | ||||
|                 src/makefile test/makefile doc/examples/makefile | ||||
|                 doc/doxyfile doc/makefile) | ||||
|  | ||||
| # copy M4 to shell | ||||
| @@ -71,18 +71,6 @@ AC_ARG_ENABLE(dot, | ||||
| test "$enableval" = "yes" && HAVE_DOT="YES" || HAVE_DOT="NO"; | ||||
| AM_PATH_CPPUNIT([1.0.0], [have_cppunit="yes"], [have_cppunit="no"]) | ||||
|  | ||||
| # Special Options | ||||
| AC_ARG_ENABLE(win, | ||||
|   [AS_HELP_STRING([--enable-win], | ||||
|                   [on linux, also builds windows version using mingw])], | ||||
|   [build_win="$enableval"], [build_win="no"]) | ||||
| AM_CONDITIONAL(BUILD_WIN, test "$build_win" = "yes") | ||||
| AC_ARG_ENABLE(32bit-linux, | ||||
|   [AS_HELP_STRING([--enable-32bit-linux], | ||||
|                   [build for 32bit linux instead of plattform specific])], | ||||
|   [build_lin32="$enableval"], [build_lin32="no"]) | ||||
| AM_CONDITIONAL(BUILD_LIN32, test "$build_lin32" = "yes") | ||||
|  | ||||
| # export macros | ||||
| SRCDIR=${srcdir} | ||||
| AC_SUBST(SRCDIR) | ||||
|   | ||||
| @@ -60,7 +60,7 @@ CREATE_SUBDIRS         = NO | ||||
| # Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish,  | ||||
| # and Ukrainian. | ||||
|  | ||||
| OUTPUT_LANGUAGE        = German | ||||
| OUTPUT_LANGUAGE        = English | ||||
|  | ||||
| # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will  | ||||
| # include brief member descriptions after the members that are listed in  | ||||
| @@ -578,7 +578,7 @@ EXCLUDE_SYMBOLS        = | ||||
| # directories that contain example code fragments that are included (see  | ||||
| # the \include command). | ||||
|  | ||||
| EXAMPLE_PATH           = . | ||||
| EXAMPLE_PATH           = @SRCDIR@/.. | ||||
|  | ||||
| # If the value of the EXAMPLE_PATH tag contains directories, you can use the  | ||||
| # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp  | ||||
|   | ||||
							
								
								
									
										62
									
								
								doc/examples/address.cxx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								doc/examples/address.cxx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | ||||
| /*! @file | ||||
|  | ||||
|     @id $Id$ | ||||
| */ | ||||
| //       1         2         3         4         5         6         7         8 | ||||
| // 45678901234567890123456789012345678901234567890123456789012345678901234567890 | ||||
|  | ||||
| // g++ -I../src ../src/xml.cxx address.cxx | ||||
|  | ||||
| #include <xml-cxx/xml.hxx> | ||||
| #include <iostream> | ||||
| #include <sstream> | ||||
| #include <fstream> | ||||
|  | ||||
| int main(int, char**) try { | ||||
|   // Example template in factory instantiation | ||||
|   xml::Factory addrTpl(xml::Node("address") | ||||
|                        <<(xml::Node("name").limits(1, 1) | ||||
|                           <<xml::String("first").limits(1, 1) | ||||
|                           <<xml::String("middle") // 0..n -> .limit(0, 0) | ||||
|                           <<xml::String("last").limits(1, 1)) | ||||
|                        <<(xml::Node("location").max(1) | ||||
|                           <<xml::String("line").min(1)) | ||||
|                        <<xml::String("email") | ||||
|                        <<xml::String("url") | ||||
|                        <<xml::String("country").max(1)); | ||||
|   // Example XML file to read | ||||
|   std::stringstream ss("\ | ||||
|       <address>\ | ||||
|         <name>\ | ||||
|           <first>Marc</first>\ | ||||
|           <middle>Roman</middle>\ | ||||
|           <last>Wäckerlin</last>\ | ||||
|         </name>\ | ||||
|         <location>\ | ||||
|           <line>SwissSign AG</line>\ | ||||
|           <line>Pfingstweidstrasse 60b</line>\ | ||||
|           <line>8005 Zürich</line>\ | ||||
|         </location>\ | ||||
|         <country>Schweiz</country>\ | ||||
|         <email>marc@waeckerlin.org</email>\ | ||||
|         <email>marc.waeckerlin@swisssign.com</email>\ | ||||
|         <url>http://dev.swisssign.com/trac/libxml-cxx</url>\ | ||||
|         <url>http://marc.wäckerlin.ch</url>\ | ||||
|         <url>http://marc.waeckerlin.org</url>\ | ||||
|         <url>http://dev.swisssign.com</url>\ | ||||
|         <url>http://swissign.com</url>\ | ||||
|         <url>http://swissign.ch</url>\ | ||||
|       </address>"); | ||||
|   std::auto_ptr<xml::Node> author(addrTpl.read(ss)); | ||||
|   // write to stdout | ||||
|   std::cout<<"Successfully read:"<<std::endl | ||||
|            <<"------------------------------"<<std::endl | ||||
|            <<*author<<std::endl | ||||
|            <<"------------------------------"<<std::endl; | ||||
|   // store in project's AUTHORS file | ||||
|   std::ofstream ofs("../AUTHORS"); | ||||
|   ofs<<*author<<std::endl; | ||||
|   return 0; | ||||
|  } catch (std::exception& e) { | ||||
|   std::cerr<<"**** Error: "<<e.what()<<std::endl; | ||||
|  } | ||||
							
								
								
									
										14
									
								
								doc/examples/makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								doc/examples/makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| ## @id $Id$ | ||||
|  | ||||
| ##       1         2         3         4         5         6         7         8 | ||||
| ## 45678901234567890123456789012345678901234567890123456789012345678901234567890 | ||||
|  | ||||
| AM_CXXFLAGS += -I ${top_srcdir}/src | ||||
| AM_LDFLAGS = -L${top_builddir}/src | ||||
|  | ||||
| noinst_PROGRAMS = address | ||||
|  | ||||
| address_SOURCES = address.cxx | ||||
| address_LDADD = -lxml-cxx | ||||
|  | ||||
| MAINTAINERCLEANFILES = makefile.in | ||||
| @@ -5,6 +5,8 @@ | ||||
| ##       1         2         3         4         5         6         7         8 | ||||
| ## 45678901234567890123456789012345678901234567890123456789012345678901234567890 | ||||
|  | ||||
| SUBDIRS = examples | ||||
|  | ||||
| develdir = ${pkgdatadir}/doc | ||||
| devel_DATA = html/index.html | ||||
|  | ||||
|   | ||||
| @@ -11,9 +11,4 @@ nobase_include_HEADERS = xml-cxx/xml.hxx | ||||
|  | ||||
| libxml_cxx_la_SOURCES = xml.cxx | ||||
|  | ||||
| if BUILD_WIN | ||||
| else | ||||
| endif | ||||
|  | ||||
| CLEANFILES =  | ||||
| MAINTAINERCLEANFILES = makefile.in | ||||
|   | ||||
| @@ -15,17 +15,72 @@ | ||||
| #include <map> | ||||
| #include <memory> | ||||
|  | ||||
| /*! @page limitations Known Limitations | ||||
| /*! @mainpage | ||||
|  | ||||
|     - Templates cannot specify number of sub-elements. | ||||
|     - XML-Comments are only ignored. | ||||
|     @section maintitle C++ XML Class Library | ||||
|  | ||||
|     - Specify your XML schema in C++ using common C++ syntax, | ||||
|       such as shift, dereference, etc. | ||||
|     - Verify the schema of XML files while they are read from a stream. | ||||
|  | ||||
|     From the README file: | ||||
|     @include README | ||||
|  | ||||
|     @page Known Limitations | ||||
|  | ||||
|     - XML-Comments are only ignored, not read, not stored. | ||||
|     - Mixed tags and text is not supported. Tags may either contain | ||||
|       other tags only (type xml::Node) or text only (type | ||||
|       xml::String). | ||||
|       xml::String). -> This is intended behaviour! | ||||
|     - Unlimited recursion is not possible | ||||
|       (e.g. <p><p><p></p></p></p>) | ||||
|     - No check yet for optional and mandatory attributes in xml::Factory | ||||
|     - Exceptions should be optional, best effort otherwise (option "strict") */ | ||||
|     - Exceptions should be optional, best effort otherwise (option "strict") | ||||
|  | ||||
|     @page rationale Rationale - Limitations of other libraries | ||||
|  | ||||
|     The initial idea was to map C++ data structures to XML files | ||||
|     (e.g. for configuration files) that can easily be edited by | ||||
|     hand. This library does not need any kind of C++ code parser or | ||||
|     proprietary pre compiler. You can specify a schema entirly in | ||||
|     native C++. Access to the XML structures is through typical C++ | ||||
|     operators which rresults in a simple and intuitive syntax. The | ||||
|     schema is verified when XML is read and exceptions are thrown when | ||||
|     the XML to be pares is invalid. Exceptions specify exactly the | ||||
|     location and reason of the problem, so that the editor of the XML | ||||
|     file can easily find and correct the problem. Due to the | ||||
|     verification, it is not necessary to check every access: Only | ||||
|     optional attributes and tags must be tested for their existence, | ||||
|     before they can be accessed. | ||||
|  | ||||
|     There are a lot of different approaches for using XML in C++, all | ||||
|     of them have their specific limitations. This library should be | ||||
|     better. | ||||
|  | ||||
|     The design is based on my experiance with gsoap | ||||
|     (http://gsoap.sf.net), boost serialization (http://boost.org) and | ||||
|     Qt XML (http://qtsoftware.com). | ||||
|      | ||||
|     @section Qt XML, a typical DOM approach | ||||
|  | ||||
|     One is the XML part of the Qt library. These classes can read XML | ||||
|     into a DOM tree, but then the user has to check for every detail. | ||||
|     This looks like: | ||||
|  | ||||
|     @code | ||||
|       QDomDocument doc; | ||||
|       if (!doc.setContent(_http.readAll())); // error | ||||
|       QDomNodeList releases(doc.elementsByTagName("release")); | ||||
|       for(int i(0); i<releases.size(); ++i) | ||||
|         if (releases.at(i).attributes().contains("type") && | ||||
|             releases.at(i).attributes().namedItem("type").nodeValue()==_name) { | ||||
|           _software = releases.at(i).firstChildElement("software"); | ||||
|           _firmware = releases.at(i).firstChildElement("firmware"); | ||||
|           if (_software.isNull() || _firmware.isNull() || | ||||
|               releases.at(i).firstChildElement("notes").isNull()); // error | ||||
|         ... | ||||
|     @endcode | ||||
|  | ||||
|     @example doc/examples/address.cxx */ | ||||
|  | ||||
| //! Represents classes for handling C++ access to XML files with strict schema. | ||||
| /*! The schema ist not presented through xsd, but it can be declared in C++. | ||||
|   | ||||
							
								
								
									
										68
									
								
								src/xml.cxx
									
									
									
									
									
								
							
							
						
						
									
										68
									
								
								src/xml.cxx
									
									
									
									
									
								
							| @@ -244,7 +244,7 @@ namespace xml { | ||||
|   //! Copy node, reset parent. | ||||
|   /*! The parent is reset, the node does not belong to the same parent | ||||
|       as the source of the copy. | ||||
|       @see xml::Node::clone for more information on the parenting. */ | ||||
|       @see xml::Node::clone() for more information on the parenting. */ | ||||
|   Node::Node(const Node& o) throw(): | ||||
|       _attributes(o._attributes), _name(o.name()), _parent(0), | ||||
|       _min(o._min), _max(o._max) { | ||||
| @@ -255,7 +255,7 @@ namespace xml { | ||||
|   //! Assign new node, keep parent. | ||||
|   /*! The parent remains unchanged, the node does not belong to the | ||||
|       same parent as the source of the copy. | ||||
|       @see xml::Node::clone for more information on the parenting. */ | ||||
|       @see xml::Node::clone() for more information on the parenting. */ | ||||
|   Node& Node::operator=(const Node& o) throw() { | ||||
|     _attributes=o._attributes; | ||||
|     _name = o.name(); | ||||
| @@ -270,7 +270,18 @@ namespace xml { | ||||
|   } | ||||
|   //! Clones But clears the parent. | ||||
|   /*! You get a new instance of the node, but detached from the | ||||
|       parent. It is then ready to be inserted below a new parent. */ | ||||
|       parent. It is then ready to be inserted below a new parent. | ||||
|        | ||||
|       If you clone (or copy) a node, the parent is not copied. This is | ||||
|       because otherwise the new now would need to be appended to the | ||||
|       parent's child list. That's most probably not | ||||
|       intended. Therefore, in a normal copy construction the parent is | ||||
|       set to @c 0 (no parent). Then the new node can be appended to a | ||||
|       parent if needed. In a copy assignment, the parent remains | ||||
|       uncanged and the other data is copied. | ||||
|  | ||||
|       The user of this library doesn't have to and is not able to care | ||||
|       about the parenting. */ | ||||
|   std::auto_ptr<Node> Node::clone() const throw() { | ||||
|     std::auto_ptr<Node> res(new Node(*this)); | ||||
|     res->_parent = 0; | ||||
| @@ -544,13 +555,6 @@ namespace xml { | ||||
|     return 0; | ||||
|   } | ||||
|   //! Clone a node, but assign a new parent. | ||||
|   /*! If you clone (or copy) a node, the parent is not copied. This is | ||||
|       because otherwise the new now would need to be appended to the | ||||
|       parent's child list. That's most probably not | ||||
|       intended. Therefore, in a normal copy operation (copy-construct | ||||
|       or copy-assign) the parent is set to @c 0 (no parent). Then the | ||||
|       new node can be appended to a parent if needed. In this method, | ||||
|       the new parent can be given in the same step. */ | ||||
|   std::auto_ptr<Node> Node::clone(Node* p) const throw() { | ||||
|     std::auto_ptr<Node> c(clone()); | ||||
|     c->_parent = p; | ||||
| @@ -643,9 +647,11 @@ namespace xml { | ||||
|     _text = ss.str(); | ||||
|     return *this; | ||||
|   } | ||||
|   //! Returns the contents as number. | ||||
|   unsigned long UnsignedInteger::number() const throw() { | ||||
|     return number(*this); | ||||
|   } | ||||
|   //! Returns the contents as number. | ||||
|   unsigned long UnsignedInteger::number(const Node& node) throw() { | ||||
|     unsigned long i(0); | ||||
|     std::stringstream ss(node.text()); | ||||
| @@ -654,6 +660,48 @@ namespace xml { | ||||
|   } | ||||
|  | ||||
|   //---------------------------------------------------------------------------- | ||||
|   //! To instanciate a factory, a template must be given. | ||||
|   /*! The template is a node that specifies the schema of the data | ||||
|       that can be loaded from streams through a xml::Factory | ||||
|       instance. | ||||
|  | ||||
|       The root element has automatically set the limits 1..1 | ||||
|       (<code>xml::Node::limits(1, 1)</code>, see xml::Node::limits), | ||||
|       which means that the root element must exist exactly once. If | ||||
|       you pass another limit, your limit is overwritten. | ||||
|  | ||||
|       E.g. to load an address, that contains a tag <address> | ||||
|       with at least a name and optional an address in it's body, you | ||||
|       may write: | ||||
|  | ||||
|       @code | ||||
|       xml::Factory addrTpl(xml::Node("address") | ||||
|                            (<<xml::Node("name").limit(1, 1) | ||||
|                             (<<xml::String("first").limit(1, 1) | ||||
|                              <<xml::String("middle") // 0..n -> .limit(0, 0) | ||||
|                              <<xml::String("last").limit(1, 1)) | ||||
|                             <<(xml::Node("location").max(1) | ||||
|                                <<xml::String("line").min(1)) | ||||
|                             <<xml::String("country").max(1))); | ||||
|       @endcode | ||||
|  | ||||
|       According to this example, a valid XML file could be: | ||||
|        | ||||
|       @verbatim | ||||
|       <address> | ||||
|         <name> | ||||
|           <first>Marc</first> | ||||
|           <middle>Roman</middle> | ||||
|           <last>Wäckerlin</last> | ||||
|         </name> | ||||
|         <location> | ||||
|           <line>SwissSign AG</line> | ||||
|           <line>Pfingstweidstrasse 60b</line> | ||||
|           <line>8005 Zürich</line> | ||||
|         </location> | ||||
|         <country>Schweiz</country> | ||||
|       </address> | ||||
|       @endverbatim */ | ||||
|   Factory::Factory(const Node& t) throw(): | ||||
|       _template(xml::Node("<xml::start>")<<t), _line(0) { | ||||
|     _template[0].min(1); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user