Main MRPT website > C++ reference for MRPT 1.5.7
xmlParser.h
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +---------------------------------------------------------------------------+ */
9 /*! \mainpage XMLParser library
10  * \section intro_sec Introduction
11  *
12  * This is a basic XML parser written in ANSI C++ for portability.
13  * It works by using recursion and a node tree for breaking
14  * down the elements of an XML document.
15 
16  * Copyright (c) 2002, Frank Vanden Berghen
17  * All rights reserved.
18  *
19  * The following license terms apply to projects that are in some way related to
20  * the "The Mobile Robot Programming Toolkit (MRPT)" project, including applications
21  * using "The Mobile Robot Programming Toolkit (MRPT)" and tools developed
22  * for enhancing "The Mobile Robot Programming Toolkit (MRPT)". All other projects
23  * (not related to "The Mobile Robot Programming Toolkit (MRPT)") have to use this
24  * code under the Aladdin Free Public License (AFPL)
25  * See the file "AFPL-license.txt" for more information about the AFPL license.
26  * (see http://www.artifex.com/downloads/doc/Public.htm for detailed AFPL terms)
27  *
28  * Redistribution and use in source and binary forms, with or without
29  * modification, are permitted provided that the following conditions are met:
30  * * Redistributions of source code must retain the above copyright
31  * notice, this list of conditions and the following disclaimer.
32  * * Redistributions in binary form must reproduce the above copyright
33  * notice, this list of conditions and the following disclaimer in the
34  * documentation and/or other materials provided with the distribution.
35  * * Neither the name of Frank Vanden Berghen nor the
36  * names of its contributors may be used to endorse or promote products
37  * derived from this software without specific prior written permission.
38  *
39  * THIS SOFTWARE IS PROVIDED BY Frank Vanden Berghen ``AS IS'' AND ANY
40  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
41  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
42  * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
43  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
44  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
46  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
47  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
48  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49  *
50  * @version V2.39
51  * @author Frank Vanden Berghen
52  *
53  * \section tutorial First Tutorial
54  * You can follow a simple <a href="../../xmlParser.html">Tutorial</a> to know the basics...
55  *
56  * \section usage General usage: How to include the XMLParser library inside your project.
57  *
58  * The library is composed of two files: <a href="../../xmlParser.cpp">xmlParser.cpp</a> and
59  * <a href="../../xmlParser.h">xmlParser.h</a>. These are the ONLY 2 files that you need when
60  * using the library inside your own projects.
61  *
62  * All the functions of the library are documented inside the comments of the file
63  * <a href="../../xmlParser.h">xmlParser.h</a>. These comments can be transformed in
64  * full-fledged HTML documentation using the DOXYGEN software: simply type: "doxygen doxy.cfg"
65  *
66  * By default, the XMLParser library uses (char*) for string representation.To use the (wchar_t*)
67  * version of the library, you need to define the "_UNICODE" preprocessor definition variable
68  * (this is usually done inside your project definition file) (This is done automatically for you
69  * when using Visual Studio).
70  *
71  * \section example Advanced Tutorial and Many Examples of usage.
72  *
73  * Some very small introductory examples are described inside the Tutorial file
74  * <a href="../../xmlParser.html">xmlParser.html</a>
75  *
76  * Some additional small examples are also inside the file <a href="../../xmlTest.cpp">xmlTest.cpp</a>
77  * (for the "char*" version of the library) and inside the file
78  * <a href="../../xmlTestUnicode.cpp">xmlTestUnicode.cpp</a> (for the "wchar_t*"
79  * version of the library). If you have a question, please review these additionnal examples
80  * before sending an e-mail to the author.
81  *
82  * To build the examples:
83  * - linux/unix: type "make"
84  * - solaris: type "make -f makefile.solaris"
85  * - windows: Visual Studio: double-click on xmlParser.dsw
86  * (under Visual Studio .NET, the .dsp and .dsw files will be automatically converted to .vcproj and .sln files)
87  *
88  * In order to build the examples you need some additional files:
89  * - linux/unix: makefile
90  * - solaris: makefile.solaris
91  * - windows: Visual Studio: *.dsp, xmlParser.dsw and also xmlParser.lib and xmlParser.dll
92  *
93  * \section debugging Debugging with the XMLParser library
94  *
95  * \subsection debugwin Debugging under WINDOWS
96  *
97  * Inside Visual C++, the "debug versions" of the memory allocation functions are
98  * very slow: Do not forget to compile in "release mode" to get maximum speed.
99  * When I have to debug a software that is using the XMLParser Library, it was usually
100  * a nightmare because the library was sooOOOoooo slow in debug mode (because of the
101  * slow memory allocations in Debug mode). To solve this
102  * problem, during all the debugging session, I use a very fast DLL version of the
103  * XMLParser Library (the DLL is compiled in release mode). Using the DLL version of
104  * the XMLParser Library allows me to have lightening XML parsing speed even in debug!
105  * Other than that, the DLL version is useless: In the release version of my tool,
106  * I always use the normal, ".cpp"-based, XMLParser Library (I simply include the
107  * <a href="../../xmlParser.cpp">xmlParser.cpp</a> and
108  * <a href="../../xmlParser.h">xmlParser.h</a> files into the project).
109  *
110  * The file <a href="../../XMLNodeAutoexp.txt">XMLNodeAutoexp.txt</a> contains some
111  * "tweaks" that improve substancially the display of the content of the XMLNode objects
112  * inside the Visual Studio Debugger. Believe me, once you have seen inside the debugger
113  * the "smooth" display of the XMLNode objects, you cannot live without it anymore!
114  *
115  * \subsection debuglinux Debugging under LINUX/UNIX
116  *
117  * The speed of the debug version of the XMLParser library is tolerable so no extra
118  * work.has been done.
119  *
120  ****************************************************************************/
121 
122 #ifndef __INCLUDE_XML_NODE__
123 #define __INCLUDE_XML_NODE__
124 
125 #include <cstdlib>
126 
127 #ifdef _UNICODE
128 // If you comment the next "define" line then the library will never "switch to" _UNICODE (wchar_t*) mode (16/32 bits per characters).
129 // This is useful when you get error messages like:
130 // 'XMLNode::openFileHelper' : cannot convert parameter 2 from 'const char [5]' to 'const wchar_t *'
131 // The _XMLWIDECHAR preprocessor variable force the XMLParser library into either utf16/32-mode (the proprocessor variable
132 // must be defined) or utf8-mode(the pre-processor variable must be undefined).
133 #define _XMLWIDECHAR
134 #endif
135 
136 #if defined(WIN32) || defined(UNDER_CE) || defined(_WIN32) || defined(WIN64) || defined(__BORLANDC__)
137 // comment the next line if you are under windows and the compiler is not Microsoft Visual Studio (6.0 or .NET) or Borland
138 #define _XMLWINDOWS
139 #endif
140 
141 #ifdef XMLDLLENTRY
142 #undef XMLDLLENTRY
143 #endif
144 #ifdef _USE_XMLPARSER_DLL
145 #ifdef _DLL_EXPORTS_
146 #define XMLDLLENTRY __declspec(dllexport)
147 #else
148 #define XMLDLLENTRY __declspec(dllimport)
149 #endif
150 #else
151 #define XMLDLLENTRY
152 #endif
153 
154 // uncomment the next line if you want no support for wchar_t* (no need for the <wchar.h> or <tchar.h> libraries anymore to compile)
155 //#define XML_NO_WIDE_CHAR
156 
157 // Mod. JLBC
158 #ifdef __BORLANDC__
159  #define XML_NO_WIDE_CHAR
160  #define strcasecmp(a,b) stricmp(a,b)
161  #define strncasecmp(a,b,c) _strnicmp(a,b,c)
162  #define _timeb timeb
163  #define _ftime(a) ftime(a)
164  #define _strnicmp(a,b,c) strnicmp(a,b,c)
165  #define _errno errno#endif
166 #endif
167 
168 #ifdef XML_NO_WIDE_CHAR
169 #undef _XMLWINDOWS
170 #undef _XMLWIDECHAR
171 #endif
172 
173 #ifdef _XMLWINDOWS
174 #include <tchar.h>
175 #else
176 #define XMLDLLENTRY
177 #ifndef XML_NO_WIDE_CHAR
178 #include <wchar.h> // to have 'wcsrtombs' for ANSI version
179  // to have 'mbsrtowcs' for WIDECHAR version
180 #endif
181 #endif
182 
183 // Some common types for char set portable code
184 #ifdef _XMLWIDECHAR
185  #define _CXML(c) L ## c
186  #define XMLCSTR const wchar_t *
187  #define XMLSTR wchar_t *
188  #define XMLCHAR wchar_t
189 #else
190  #define _CXML(c) c
191  #define XMLCSTR const char *
192  #define XMLSTR char *
193  #define XMLCHAR char
194 #endif
195 #ifndef FALSE
196  #define FALSE 0
197 #endif /* FALSE */
198 #ifndef TRUE
199  #define TRUE 1
200 #endif /* TRUE */
201 
202 
203 /// Enumeration for XML parse errors.
204 typedef enum XMLError
205 {
223 
228 } XMLError;
229 
230 
231 /// Enumeration used to manage type of data. Use in conjunction with structure XMLNodeContents
232 typedef enum XMLElementType
233 {
240 
241 /// Structure used to obtain error details if the parse fails.
242 typedef struct XMLResults
243 {
246 } XMLResults;
247 
248 /// Structure for XML clear (unformatted) node (usually comments)
249 typedef struct XMLClear {
251 } XMLClear;
252 
253 /// Structure for XML attribute.
254 typedef struct XMLAttribute {
256 } XMLAttribute;
257 
258 /// XMLElementPosition are not interchangeable with simple indexes
259 typedef int XMLElementPosition;
260 
261 struct XMLNodeContents;
262 
263 /** @defgroup XMLParserGeneral The XML parser */
264 
265 /// Main Class representing a XML node
266 /**
267  * All operations are performed using this class.
268  * \note The constructors of the XMLNode class are protected, so use instead one of these four methods to get your first instance of XMLNode:
269  * <ul>
270  * <li> XMLNode::parseString </li>
271  * <li> XMLNode::parseFile </li>
272  * <li> XMLNode::openFileHelper </li>
273  * <li> XMLNode::createXMLTopNode (or XMLNode::createXMLTopNode_WOSD)</li>
274  * </ul> */
275 typedef struct XMLDLLENTRY XMLNode
276 {
277  private:
278 
279  struct XMLNodeDataTag;
280 
281  /// Constructors are protected, so use instead one of: XMLNode::parseString, XMLNode::parseFile, XMLNode::openFileHelper, XMLNode::createXMLTopNode
282  XMLNode(struct XMLNodeDataTag *pParent, XMLSTR lpszName, char isDeclaration);
283  /// Constructors are protected, so use instead one of: XMLNode::parseString, XMLNode::parseFile, XMLNode::openFileHelper, XMLNode::createXMLTopNode
284  XMLNode(struct XMLNodeDataTag *p);
285 
286  public:
287  static XMLCSTR getVersion();///< Return the XMLParser library version number
288 
289  /** @defgroup conversions Parsing XML files/strings to an XMLNode structure and Rendering XMLNode's to files/string.
290  * @ingroup XMLParserGeneral
291  * @{ */
292 
293  /// Parse an XML string and return the root of a XMLNode tree representing the string.
294  static XMLNode parseString (XMLCSTR lpXMLString, XMLCSTR tag=NULL, XMLResults *pResults=NULL);
295  /**< The "parseString" function parse an XML string and return the root of a XMLNode tree. The "opposite" of this function is
296  * the function "createXMLString" that re-creates an XML string from an XMLNode tree. If the XML document is corrupted, the
297  * "parseString" method will initialize the "pResults" variable with some information that can be used to trace the error.
298  * If you still want to parse the file, you can use the APPROXIMATE_PARSING option as explained inside the note at the
299  * beginning of the "xmlParser.cpp" file.
300  *
301  * @param lpXMLString the XML string to parse
302  * @param tag the name of the first tag inside the XML file. If the tag parameter is omitted, this function returns a node that represents the head of the xml document including the declaration term (<? ... ?>).
303  * @param pResults a pointer to a XMLResults variable that will contain some information that can be used to trace the XML parsing error. You can have a user-friendly explanation of the parsing error with the "getError" function.
304  */
305 
306  /// Parse an XML file and return the root of a XMLNode tree representing the file.
307  static XMLNode parseFile (XMLCSTR filename, XMLCSTR tag=NULL, XMLResults *pResults=NULL);
308  /**< The "parseFile" function parse an XML file and return the root of a XMLNode tree. The "opposite" of this function is
309  * the function "writeToFile" that re-creates an XML file from an XMLNode tree. If the XML document is corrupted, the
310  * "parseFile" method will initialize the "pResults" variable with some information that can be used to trace the error.
311  * If you still want to parse the file, you can use the APPROXIMATE_PARSING option as explained inside the note at the
312  * beginning of the "xmlParser.cpp" file.
313  *
314  * @param filename the path to the XML file to parse
315  * @param tag the name of the first tag inside the XML file. If the tag parameter is omitted, this function returns a node that represents the head of the xml document including the declaration term (<? ... ?>).
316  * @param pResults a pointer to a XMLResults variable that will contain some information that can be used to trace the XML parsing error. You can have a user-friendly explanation of the parsing error with the "getError" function.
317  */
318 
319  /// Parse an XML file and return the root of a XMLNode tree representing the file. A very crude error checking is made. An attempt to guess the Char Encoding used in the file is made.
320  static XMLNode openFileHelper(XMLCSTR filename, XMLCSTR tag=NULL);
321  /**< The "openFileHelper" function reports to the screen all the warnings and errors that occurred during parsing of the XML file.
322  * This function also tries to guess char Encoding (UTF-8, ASCII or SHIT-JIS) based on the first 200 bytes of the file. Since each
323  * application has its own way to report and deal with errors, you should rather use the "parseFile" function to parse XML files
324  * and program yourself thereafter an "error reporting" tailored for your needs (instead of using the very crude "error reporting"
325  * mechanism included inside the "openFileHelper" function).
326  *
327  * If the XML document is corrupted, the "openFileHelper" method will:
328  * - display an error message on the console (or inside a messageBox for windows).
329  * - stop execution (exit).
330  *
331  * I strongly suggest that you write your own "openFileHelper" method tailored to your needs. If you still want to parse
332  * the file, you can use the APPROXIMATE_PARSING option as explained inside the note at the beginning of the "xmlParser.cpp" file.
333  *
334  * @param filename the path of the XML file to parse.
335  * @param tag the name of the first tag inside the XML file. If the tag parameter is omitted, this function returns a node that represents the head of the xml document including the declaration term (<? ... ?>).
336  */
337 
338  static XMLCSTR getError(XMLError error); ///< this gives you a user-friendly explanation of the parsing error
339 
340  /// Create an XML string starting from the current XMLNode.
341  XMLSTR createXMLString(int nFormat=1, int *pnSize=NULL) const;
342  /**< The returned string should be free'd using the "freeXMLString" function.
343  *
344  * If nFormat==0, no formatting is required otherwise this returns an user friendly XML string from a given element
345  * with appropriate white spaces and carriage returns. if pnSize is given it returns the size in character of the string. */
346 
347  /// Save the content of an xmlNode inside a file
348  XMLError writeToFile(XMLCSTR filename,
349  const char *encoding=NULL,
350  char nFormat=1) const;
351  /**< If nFormat==0, no formatting is required otherwise this returns an user friendly XML string from a given element with appropriate white spaces and carriage returns.
352  * If the global parameter "characterEncoding==encoding_UTF8", then the "encoding" parameter is ignored and always set to "utf-8".
353  * If the global parameter "characterEncoding==encoding_ShiftJIS", then the "encoding" parameter is ignored and always set to "SHIFT-JIS".
354  * If "_XMLWIDECHAR=1", then the "encoding" parameter is ignored and always set to "utf-16".
355  * If no "encoding" parameter is given the "ISO-8859-1" encoding is used. */
356  /** @} */
357 
358  /** @defgroup navigate Navigate the XMLNode structure
359  * @ingroup XMLParserGeneral
360  * @{ */
361  XMLCSTR getName() const; ///< name of the node
362  XMLCSTR getText(int i=0) const; ///< return ith text field
363  int nText() const; ///< nbr of text field
364  XMLNode getParentNode() const; ///< return the parent node
365  XMLNode getChildNode(int i=0) const; ///< return ith child node
366  XMLNode getChildNode(XMLCSTR name, int i) const; ///< return ith child node with specific name (return an empty node if failing). If i==-1, this returns the last XMLNode with the given name.
367  XMLNode getChildNode(XMLCSTR name, int *i=NULL) const; ///< return next child node with specific name (return an empty node if failing)
368  XMLNode getChildNodeWithAttribute(XMLCSTR tagName,
369  XMLCSTR attributeName,
370  XMLCSTR attributeValue=NULL,
371  int *i=NULL) const; ///< return child node with specific name/attribute (return an empty node if failing)
372  XMLNode getChildNodeByPath(XMLSTR path, char createNodeIfMissing=0, XMLCHAR sep='/');
373  ///< return the first child node with specific path. WARNING: the value of the parameter "path" is destroyed!
374  XMLNode getChildNodeByPath(XMLCSTR path, char createNodeIfMissing=0, XMLCHAR sep='/');
375  ///< return the first child node with specific path
376 
377  int nChildNode(XMLCSTR name) const; ///< return the number of child node with specific name
378  int nChildNode() const; ///< nbr of child node
379  XMLAttribute getAttribute(int i=0) const; ///< return ith attribute
380  XMLCSTR getAttributeName(int i=0) const; ///< return ith attribute name
381  XMLCSTR getAttributeValue(int i=0) const; ///< return ith attribute value
382  char isAttributeSet(XMLCSTR name) const; ///< test if an attribute with a specific name is given
383  XMLCSTR getAttribute(XMLCSTR name, int i) const; ///< return ith attribute content with specific name (return a NULL if failing)
384  XMLCSTR getAttribute(XMLCSTR name, int *i=NULL) const; ///< return next attribute content with specific name (return a NULL if failing)
385  int nAttribute() const; ///< nbr of attribute
386  XMLClear getClear(int i=0) const; ///< return ith clear field (comments)
387  int nClear() const; ///< nbr of clear field
388  XMLNodeContents enumContents(XMLElementPosition i) const; ///< enumerate all the different contents (attribute,child,text, clear) of the current XMLNode. The order is reflecting the order of the original file/string. NOTE: 0 <= i < nElement();
389  int nElement() const; ///< nbr of different contents for current node
390  char isEmpty() const; ///< is this node Empty?
391  char isDeclaration() const; ///< is this node a declaration <? .... ?>
392  XMLNode deepCopy() const; ///< deep copy (duplicate/clone) a XMLNode
393  static XMLNode emptyNode(); ///< return XMLNode::emptyXMLNode;
394  /** @} */
395 
396  ~XMLNode();
397  XMLNode(const XMLNode &A); ///< to allow shallow/fast copy:
398  XMLNode& operator=( const XMLNode& A ); ///< to allow shallow/fast copy:
399 
400  XMLNode(): d(NULL){};
401  static XMLNode emptyXMLNode;
404 
405  /** @defgroup xmlModify Create or Update the XMLNode structure
406  * @ingroup XMLParserGeneral
407  * The functions in this group allows you to create from scratch (or update) a XMLNode structure. Start by creating your top
408  * node with the "createXMLTopNode" function and then add new nodes with the "addChild" function. The parameter 'pos' gives
409  * the position where the childNode, the text or the XMLClearTag will be inserted. The default value (pos=-1) inserts at the
410  * end. The value (pos=0) insert at the beginning (Insertion at the beginning is slower than at the end). <br>
411  *
412  * REMARK: 0 <= pos < nChild()+nText()+nClear() <br>
413  */
414 
415  /** @defgroup creation Creating from scratch a XMLNode structure
416  * @ingroup xmlModify
417  * @{ */
418  static XMLNode createXMLTopNode(XMLCSTR lpszName, char isDeclaration=FALSE); ///< Create the top node of an XMLNode structure
419  XMLNode addChild(XMLCSTR lpszName, char isDeclaration=FALSE, XMLElementPosition pos=-1); ///< Add a new child node
420  XMLNode addChild(XMLNode nodeToAdd, XMLElementPosition pos=-1); ///< If the "nodeToAdd" has some parents, it will be detached from it's parents before being attached to the current XMLNode
421  XMLAttribute *addAttribute(XMLCSTR lpszName, XMLCSTR lpszValuev); ///< Add a new attribute
422  XMLCSTR addText(XMLCSTR lpszValue, XMLElementPosition pos=-1); ///< Add a new text content
423  XMLClear *addClear(XMLCSTR lpszValue, XMLCSTR lpszOpen=NULL, XMLCSTR lpszClose=NULL, XMLElementPosition pos=-1);
424  /**< Add a new clear tag
425  * @param lpszOpen default value "<![CDATA["
426  * @param lpszClose default value "]]>"
427  */
428  /** @} */
429 
430  /** @defgroup xmlUpdate Updating Nodes
431  * @ingroup xmlModify
432  * Some update functions:
433  * @{
434  */
435  XMLCSTR updateName(XMLCSTR lpszName); ///< change node's name
436  XMLAttribute *updateAttribute(XMLAttribute *newAttribute, XMLAttribute *oldAttribute); ///< if the attribute to update is missing, a new one will be added
437  XMLAttribute *updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName=NULL,int i=0); ///< if the attribute to update is missing, a new one will be added
438  XMLAttribute *updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName,XMLCSTR lpszOldName);///< set lpszNewName=NULL if you don't want to change the name of the attribute if the attribute to update is missing, a new one will be added
439  XMLCSTR updateText(XMLCSTR lpszNewValue, int i=0); ///< if the text to update is missing, a new one will be added
440  XMLCSTR updateText(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue); ///< if the text to update is missing, a new one will be added
441  XMLClear *updateClear(XMLCSTR lpszNewContent, int i=0); ///< if the clearTag to update is missing, a new one will be added
442  XMLClear *updateClear(XMLClear *newP,XMLClear *oldP); ///< if the clearTag to update is missing, a new one will be added
443  XMLClear *updateClear(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue); ///< if the clearTag to update is missing, a new one will be added
444  /** @} */
445 
446  /** @defgroup xmlDelete Deleting Nodes or Attributes
447  * @ingroup xmlModify
448  * Some deletion functions:
449  * @{
450  */
451  /// The "deleteNodeContent" function forces the deletion of the content of this XMLNode and the subtree.
452  void deleteNodeContent();
453  /**< \note The XMLNode instances that are referring to the part of the subtree that has been deleted CANNOT be used anymore!!. Unexpected results will occur if you continue using them. */
454  void deleteAttribute(int i=0); ///< Delete the ith attribute of the current XMLNode
455  void deleteAttribute(XMLCSTR lpszName); ///< Delete the attribute with the given name (the "strcmp" function is used to find the right attribute)
456  void deleteAttribute(XMLAttribute *anAttribute); ///< Delete the attribute with the name "anAttribute->lpszName" (the "strcmp" function is used to find the right attribute)
457  void deleteText(int i=0); ///< Delete the Ith text content of the current XMLNode
458  void deleteText(XMLCSTR lpszValue); ///< Delete the text content "lpszValue" inside the current XMLNode (direct "pointer-to-pointer" comparison is used to find the right text)
459  void deleteClear(int i=0); ///< Delete the Ith clear tag inside the current XMLNode
460  void deleteClear(XMLCSTR lpszValue); ///< Delete the clear tag "lpszValue" inside the current XMLNode (direct "pointer-to-pointer" comparison is used to find the clear tag)
461  void deleteClear(XMLClear *p); ///< Delete the clear tag "p" inside the current XMLNode (direct "pointer-to-pointer" comparison on the lpszName of the clear tag is used to find the clear tag)
462  /** @} */
463 
464  /** @defgroup xmlWOSD ???_WOSD functions.
465  * @ingroup xmlModify
466  * The strings given as parameters for the "add" and "update" methods that have a name with
467  * the postfix "_WOSD" (that means "WithOut String Duplication")(for example "addText_WOSD")
468  * will be free'd by the XMLNode class. For example, it means that this is incorrect:
469  * \code
470  * xNode.addText_WOSD("foo");
471  * xNode.updateAttribute_WOSD("#newcolor" ,NULL,"color");
472  * \endcode
473  * In opposition, this is correct:
474  * \code
475  * xNode.addText("foo");
476  * xNode.addText_WOSD(stringDup("foo"));
477  * xNode.updateAttribute("#newcolor" ,NULL,"color");
478  * xNode.updateAttribute_WOSD(stringDup("#newcolor"),NULL,"color");
479  * \endcode
480  * Typically, you will never do:
481  * \code
482  * char *b=(char*)malloc(...);
483  * xNode.addText(b);
484  * free(b);
485  * \endcode
486  * ... but rather:
487  * \code
488  * char *b=(char*)malloc(...);
489  * xNode.addText_WOSD(b);
490  * \endcode
491  * ('free(b)' is performed by the XMLNode class)
492  * @{ */
493  static XMLNode createXMLTopNode_WOSD(XMLSTR lpszName, char isDeclaration=FALSE); ///< Create the top node of an XMLNode structure
494  XMLNode addChild_WOSD(XMLSTR lpszName, char isDeclaration=FALSE, XMLElementPosition pos=-1); ///< Add a new child node
495  XMLAttribute *addAttribute_WOSD(XMLSTR lpszName, XMLSTR lpszValue); ///< Add a new attribute
496  XMLCSTR addText_WOSD(XMLSTR lpszValue, XMLElementPosition pos=-1); ///< Add a new text content
497  XMLClear *addClear_WOSD(XMLSTR lpszValue, XMLCSTR lpszOpen=NULL, XMLCSTR lpszClose=NULL, XMLElementPosition pos=-1); ///< Add a new clear Tag
498 
499  XMLCSTR updateName_WOSD(XMLSTR lpszName); ///< change node's name
500  XMLAttribute *updateAttribute_WOSD(XMLAttribute *newAttribute, XMLAttribute *oldAttribute); ///< if the attribute to update is missing, a new one will be added
501  XMLAttribute *updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName=NULL,int i=0); ///< if the attribute to update is missing, a new one will be added
502  XMLAttribute *updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName,XMLCSTR lpszOldName); ///< set lpszNewName=NULL if you don't want to change the name of the attribute if the attribute to update is missing, a new one will be added
503  XMLCSTR updateText_WOSD(XMLSTR lpszNewValue, int i=0); ///< if the text to update is missing, a new one will be added
504  XMLCSTR updateText_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue); ///< if the text to update is missing, a new one will be added
505  XMLClear *updateClear_WOSD(XMLSTR lpszNewContent, int i=0); ///< if the clearTag to update is missing, a new one will be added
506  XMLClear *updateClear_WOSD(XMLClear *newP,XMLClear *oldP); ///< if the clearTag to update is missing, a new one will be added
507  XMLClear *updateClear_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue); ///< if the clearTag to update is missing, a new one will be added
508  /** @} */
509 
510  /** @defgroup xmlPosition Position helper functions (use in conjunction with the update&add functions
511  * @ingroup xmlModify
512  * These are some useful functions when you want to insert a childNode, a text or a XMLClearTag in the
513  * middle (at a specified position) of a XMLNode tree already constructed. The value returned by these
514  * methods is to be used as last parameter (parameter 'pos') of addChild, addText or addClear.
515  * @{ */
516  XMLElementPosition positionOfText(int i=0) const;
517  XMLElementPosition positionOfText(XMLCSTR lpszValue) const;
518  XMLElementPosition positionOfClear(int i=0) const;
519  XMLElementPosition positionOfClear(XMLCSTR lpszValue) const;
520  XMLElementPosition positionOfClear(XMLClear *a) const;
521  XMLElementPosition positionOfChildNode(int i=0) const;
522  XMLElementPosition positionOfChildNode(XMLNode x) const;
523  XMLElementPosition positionOfChildNode(XMLCSTR name, int i=0) const; ///< return the position of the ith childNode with the specified name if (name==NULL) return the position of the ith childNode
524  /** @} */
525 
526  /// Enumeration for XML character encoding.
527  typedef enum XMLCharEncoding
528  {
529  char_encoding_error=0,
530  char_encoding_UTF8=1,
531  char_encoding_legacy=2,
532  char_encoding_ShiftJIS=3,
533  char_encoding_GB2312=4,
534  char_encoding_Big5=5,
535  char_encoding_GBK=6 // this is actually the same as Big5
536  } XMLCharEncoding;
537 
538  /** \addtogroup conversions
539  * @{ */
540 
541  /// Sets the global options for the conversions
542  static char setGlobalOptions(XMLCharEncoding characterEncoding=XMLNode::char_encoding_UTF8, char guessWideCharChars=1,
544  /**< The "setGlobalOptions" function allows you to change four global parameters that affect string & file
545  * parsing. First of all, you most-probably will never have to change these 3 global parameters.
546  *
547  * @param guessWideCharChars If "guessWideCharChars"=1 and if this library is compiled in WideChar mode, then the
548  * XMLNode::parseFile and XMLNode::openFileHelper functions will test if the file contains ASCII
549  * characters. If this is the case, then the file will be loaded and converted in memory to
550  * WideChar before being parsed. If 0, no conversion will be performed.
551  *
552  * @param guessWideCharChars If "guessWideCharChars"=1 and if this library is compiled in ASCII/UTF8/char* mode, then the
553  * XMLNode::parseFile and XMLNode::openFileHelper functions will test if the file contains WideChar
554  * characters. If this is the case, then the file will be loaded and converted in memory to
555  * ASCII/UTF8/char* before being parsed. If 0, no conversion will be performed.
556  *
557  * @param characterEncoding This parameter is only meaningful when compiling in char* mode (multibyte character mode).
558  * In wchar_t* (wide char mode), this parameter is ignored. This parameter should be one of the
559  * three currently recognized encodings: XMLNode::encoding_UTF8, XMLNode::encoding_ascii,
560  * XMLNode::encoding_ShiftJIS.
561  *
562  * @param dropWhiteSpace In most situations, text fields containing only white spaces (and carriage returns)
563  * are useless. Even more, these "empty" text fields are annoying because they increase the
564  * complexity of the user's code for parsing. So, 99% of the time, it's better to drop
565  * the "empty" text fields. However The XML specification indicates that no white spaces
566  * should be lost when parsing the file. So to be perfectly XML-compliant, you should set
567  * dropWhiteSpace=0. A note of caution: if you set "dropWhiteSpace=0", the parser will be
568  * slower and your code will be more complex.
569  *
570  * @param removeCommentsInMiddleOfText To explain this parameter, let's consider this code:
571  * \code
572  * XMLNode x=XMLNode::parseString("<a>foo<!-- hello -->bar<!DOCTYPE world >chu</a>","a");
573  * \endcode
574  * If removeCommentsInMiddleOfText=0, then we will have:
575  * \code
576  * x.getText(0) -> "foo"
577  * x.getText(1) -> "bar"
578  * x.getText(2) -> "chu"
579  * x.getClear(0) --> "<!-- hello -->"
580  * x.getClear(1) --> "<!DOCTYPE world >"
581  * \endcode
582  * If removeCommentsInMiddleOfText=1, then we will have:
583  * \code
584  * x.getText(0) -> "foobar"
585  * x.getText(1) -> "chu"
586  * x.getClear(0) --> "<!DOCTYPE world >"
587  * \endcode
588  *
589  * \return "0" when there are no errors. If you try to set an unrecognized encoding then the return value will be "1" to signal an error.
590  *
591  * \note Sometime, it's useful to set "guessWideCharChars=0" to disable any conversion
592  * because the test to detect the file-type (ASCII/UTF8/char* or WideChar) may fail (rarely). */
593 
594  /// Guess the character encoding of the string (ascii, utf8 or shift-JIS)
595  static XMLCharEncoding guessCharEncoding(void *buffer, int bufLen, char useXMLEncodingAttribute=1);
596  /**< The "guessCharEncoding" function try to guess the character encoding. You most-probably will never
597  * have to use this function. It then returns the appropriate value of the global parameter
598  * "characterEncoding" described in the XMLNode::setGlobalOptions. The guess is based on the content of a buffer of length
599  * "bufLen" bytes that contains the first bytes (minimum 25 bytes; 200 bytes is a good value) of the
600  * file to be parsed. The XMLNode::openFileHelper function is using this function to automatically compute
601  * the value of the "characterEncoding" global parameter. There are several heuristics used to do the
602  * guess. One of the heuristic is based on the "encoding" attribute. The original XML specifications
603  * forbids to use this attribute to do the guess but you can still use it if you set
604  * "useXMLEncodingAttribute" to 1 (this is the default behavior and the behavior of most parsers).
605  * If an inconsistency in the encoding is detected, then the return value is "0". */
606  /** @} */
607 
608  private:
609  // these are functions and structures used internally by the XMLNode class (don't bother about them):
610 
611  typedef struct XMLNodeDataTag // to allow shallow copy and "intelligent/smart" pointers (automatic delete):
612  {
613  XMLCSTR lpszName; // Element name (=NULL if root)
614  int nChild, // Number of child nodes
615  nText, // Number of text fields
616  nClear, // Number of Clear fields (comments)
617  nAttribute; // Number of attributes
618  char isDeclaration; // Whether node is an XML declaration - '<?xml ?>'
619  struct XMLNodeDataTag *pParent; // Pointer to parent element (=NULL if root)
620  XMLNode *pChild; // Array of child nodes
621  XMLCSTR *pText; // Array of text fields
622  XMLClear *pClear; // Array of clear fields
623  XMLAttribute *pAttribute; // Array of attributes
624  int *pOrder; // order of the child_nodes,text_fields,clear_fields
625  int ref_count; // for garbage collection (smart pointers)
626  } XMLNodeData;
628 
629  char parseClearTag(void *px, void *pa);
630  char maybeAddTxT(void *pa, XMLCSTR tokenPStr);
631  int ParseXMLElement(void *pXML);
632  void *addToOrder(int memInc, int *_pos, int nc, void *p, int size, XMLElementType xtype);
633  int indexText(XMLCSTR lpszValue) const;
634  int indexClear(XMLCSTR lpszValue) const;
635  XMLNode addChild_priv(int,XMLSTR,char,int);
636  XMLAttribute *addAttribute_priv(int,XMLSTR,XMLSTR);
637  XMLCSTR addText_priv(int,XMLSTR,int);
638  XMLClear *addClear_priv(int,XMLSTR,XMLCSTR,XMLCSTR,int);
639  void emptyTheNode(char force);
640  static inline XMLElementPosition findPosition(XMLNodeData *d, int index, XMLElementType xtype);
641  static int CreateXMLStringR(XMLNodeData *pEntry, XMLSTR lpszMarker, int nFormat);
642  static int removeOrderElement(XMLNodeData *d, XMLElementType t, int index);
643  static void exactMemory(XMLNodeData *d);
644  static int detachFromParent(XMLNodeData *d);
645 } XMLNode;
646 
647 /// This structure is given by the function XMLNode::enumContents.
648 typedef struct XMLNodeContents
649 {
650  /// This dictates what's the content of the XMLNodeContent
652  /**< should be an union to access the appropriate data. Compiler does not allow union of object with constructor... too bad. */
657 
659 
660 /** @defgroup StringAlloc String Allocation/Free functions
661  * @ingroup xmlModify
662  * @{ */
663 /// Duplicate (copy in a new allocated buffer) the source string.
664 XMLDLLENTRY XMLSTR stringDup(XMLCSTR source, int cbData=-1);
665 /**< This is
666  * a very handy function when used with all the "XMLNode::*_WOSD" functions (\link xmlWOSD \endlink).
667  * @param cbData If !=0 then cbData is the number of chars to duplicate. New strings allocated with
668  * this function should be free'd using the "freeXMLString" function. */
669 
670 /// to free the string allocated inside the "stringDup" function or the "createXMLString" function.
671 XMLDLLENTRY void freeXMLString(XMLSTR t); // {free(t);}
672 /** @} */
673 
674 /** @defgroup atoX ato? like functions
675  * @ingroup XMLParserGeneral
676  * The "xmlto?" functions are equivalents to the atoi, atol, atof functions.
677  * The only difference is: If the variable "xmlString" is NULL, than the return value
678  * is "defautValue". These 6 functions are only here as "convenience" functions for the
679  * user (they are not used inside the XMLparser). If you don't need them, you can
680  * delete them without any trouble.
681  *
682  * @{ */
683 XMLDLLENTRY char xmltob(XMLCSTR xmlString,char defautValue=0);
684 XMLDLLENTRY int xmltoi(XMLCSTR xmlString,int defautValue=0);
685 XMLDLLENTRY long xmltol(XMLCSTR xmlString,long defautValue=0);
686 XMLDLLENTRY double xmltof(XMLCSTR xmlString,double defautValue=.0);
687 XMLDLLENTRY XMLCSTR xmltoa(XMLCSTR xmlString,XMLCSTR defautValue=_CXML(""));
688 XMLDLLENTRY XMLCHAR xmltoc(XMLCSTR xmlString,XMLCHAR defautValue=_CXML('\0'));
689 /** @} */
690 
691 /** @defgroup ToXMLStringTool Helper class to create XML files using "printf", "fprintf", "cout",... functions.
692  * @ingroup XMLParserGeneral
693  * @{ */
694 /// Helper class to create XML files using "printf", "fprintf", "cout",... functions.
695 /** The ToXMLStringTool class helps you creating XML files using "printf", "fprintf", "cout",... functions.
696  * The "ToXMLStringTool" class is processing strings so that all the characters
697  * &,",',<,> are replaced by their XML equivalent:
698  * \verbatim &amp;, &quot;, &apos;, &lt;, &gt; \endverbatim
699  * Using the "ToXMLStringTool class" and the "fprintf function" is THE most efficient
700  * way to produce VERY large XML documents VERY fast.
701  * \note If you are creating from scratch an XML file using the provided XMLNode class
702  * you must not use the "ToXMLStringTool" class (because the "XMLNode" class does the
703  * processing job for you during rendering).*/
705 {
706 public:
707  ToXMLStringTool(): buf(NULL),buflen(0){}
708  ~ToXMLStringTool();
709  void freeBuffer();///<call this function when you have finished using this object to release memory used by the internal buffer.
710 
711  XMLSTR toXML(XMLCSTR source);///< returns a pointer to an internal buffer that contains a XML-encoded string based on the "source" parameter.
712 
713  /** The "toXMLUnSafe" function is deprecated because there is a possibility of
714  * "destination-buffer-overflow". It converts the string
715  * "source" to the string "dest". */
716  static XMLSTR toXMLUnSafe(XMLSTR dest,XMLCSTR source); ///< deprecated: use "toXML" instead
717  static int lengthXMLString(XMLCSTR source); ///< deprecated: use "toXML" instead
718 
719 private:
721  int buflen;
723 /** @} */
724 
725 /** @defgroup XMLParserBase64Tool Helper class to include binary data inside XML strings using "Base64 encoding".
726  * @ingroup XMLParserGeneral
727  * @{ */
728 /// Helper class to include binary data inside XML strings using "Base64 encoding".
729 /** The "XMLParserBase64Tool" class allows you to include any binary data (images, sounds,...)
730  * into an XML document using "Base64 encoding". This class is completely
731  * separated from the rest of the xmlParser library and can be removed without any problem.
732  * To include some binary data into an XML file, you must convert the binary data into
733  * standard text (using "encode"). To retrieve the original binary data from the
734  * b64-encoded text included inside the XML file, use "decode". Alternatively, these
735  * functions can also be used to "encrypt/decrypt" some critical data contained inside
736  * the XML (it's not a strong encryption at all, but sometimes it can be useful). */
738 {
739 public:
740  XMLParserBase64Tool(): buf(NULL),buflen(0){}
742  void freeBuffer();///< Call this function when you have finished using this object to release memory used by the internal buffer.
743 
744  /**
745  * @param formatted If "formatted"=true, some space will be reserved for a carriage-return every 72 chars. */
746  static int encodeLength(int inBufLen, char formatted=0); ///< return the length of the base64 string that encodes a data buffer of size inBufLen bytes.
747 
748  /**
749  * The "base64Encode" function returns a string containing the base64 encoding of "inByteLen" bytes
750  * from "inByteBuf". If "formatted" parameter is true, then there will be a carriage-return every 72 chars.
751  * The string will be free'd when the XMLParserBase64Tool object is deleted.
752  * All returned strings are sharing the same memory space. */
753  XMLSTR encode(unsigned char *inByteBuf, unsigned int inByteLen, char formatted=0); ///< returns a pointer to an internal buffer containing the base64 string containing the binary data encoded from "inByteBuf"
754 
755  /// returns the number of bytes which will be decoded from "inString".
756  static unsigned int decodeSize(XMLCSTR inString, XMLError *xe=NULL);
757 
758  /**
759  * The "decode" function returns a pointer to a buffer containing the binary data decoded from "inString"
760  * The output buffer will be free'd when the XMLParserBase64Tool object is deleted.
761  * All output buffer are sharing the same memory space.
762  * @param inString If "instring" is malformed, NULL will be returned */
763  unsigned char* decode(XMLCSTR inString, int *outByteLen=NULL, XMLError *xe=NULL); ///< returns a pointer to an internal buffer containing the binary data decoded from "inString"
764 
765  /**
766  * decodes data from "inString" to "outByteBuf". You need to provide the size (in byte) of "outByteBuf"
767  * in "inMaxByteOutBuflen". If "outByteBuf" is not large enough or if data is malformed, then "FALSE"
768  * will be returned; otherwise "TRUE". */
769  static unsigned char decode(XMLCSTR inString, unsigned char *outByteBuf, int inMaxByteOutBuflen, XMLError *xe=NULL); ///< deprecated.
770 
771 private:
772  void *buf;
773  int buflen;
774  void alloc(int newsize);
776 /** @} */
777 
778 #undef XMLDLLENTRY
779 
780 #endif
Helper class to create XML files using "printf", "fprintf", "cout",... functions. ...
Definition: xmlParser.h:704
XMLElementType
Enumeration used to manage type of data. Use in conjunction with structure XMLNodeContents.
Definition: xmlParser.h:232
#define _CXML(c)
Definition: xmlParser.h:190
XMLDLLENTRY XMLCHAR xmltoc(XMLCSTR xmlString, XMLCHAR defautValue=_CXML('\0'))
Definition: xmlParser.cpp:318
GLdouble GLdouble t
Definition: glext.h:3610
#define XMLCHAR
Definition: xmlParser.h:193
enum XMLElementType etype
This dictates what&#39;s the content of the XMLNodeContent.
Definition: xmlParser.h:651
XMLCSTR lpszOpenTag
Definition: xmlParser.h:250
Main Class representing a XML node.
Definition: xmlParser.h:275
int nColumn
Definition: xmlParser.h:245
GLuint buffer
Definition: glext.h:3775
XMLCharEncoding
Enumeration for XML character encoding.
Definition: xmlParser.h:527
struct XMLNodeContents XMLNodeContents
This structure is given by the function XMLNode::enumContents.
Structure for XML clear (unformatted) node (usually comments)
Definition: xmlParser.h:249
This structure is given by the function XMLNode::enumContents.
Definition: xmlParser.h:648
XMLDLLENTRY XMLSTR stringDup(XMLCSTR source, int cbData=-1)
Duplicate (copy in a new allocated buffer) the source string.
Definition: xmlParser.cpp:571
int XMLElementPosition
XMLElementPosition are not interchangeable with simple indexes.
Definition: xmlParser.h:259
#define XMLCSTR
Definition: xmlParser.h:191
struct XMLClear XMLClear
Structure for XML clear (unformatted) node (usually comments)
static XMLClear emptyXMLClear
Definition: xmlParser.h:402
struct XMLDLLENTRY ToXMLStringTool ToXMLStringTool
Helper class to create XML files using "printf", "fprintf", "cout",... functions. ...
XMLNodeData * d
Definition: xmlParser.h:627
#define XMLDLLENTRY
Definition: xmlParser.h:151
struct XMLResults XMLResults
Structure used to obtain error details if the parse fails.
struct XMLAttribute XMLAttribute
Structure for XML attribute.
XMLNode()
Definition: xmlParser.h:400
GLuint index
Definition: glext.h:3891
XMLError
Enumeration for XML parse errors.
Definition: xmlParser.h:204
XMLDLLENTRY XMLCSTR xmltoa(XMLCSTR xmlString, XMLCSTR defautValue=_CXML(""))
Definition: xmlParser.cpp:317
#define XMLSTR
Definition: xmlParser.h:192
static XMLNode::XMLCharEncoding characterEncoding
Definition: xmlParser.cpp:30
XMLCSTR lpszValue
Definition: xmlParser.h:250
XMLAttribute * pAttribute
Definition: xmlParser.h:623
static char dropWhiteSpace
Definition: xmlParser.cpp:31
struct XMLNode::XMLNodeDataTag XMLNodeData
struct XMLNodeDataTag * pParent
Definition: xmlParser.h:619
static XMLAttribute emptyXMLAttribute
Definition: xmlParser.h:403
XMLCSTR lpszName
Definition: xmlParser.h:255
XMLNode child
Definition: xmlParser.h:653
Helper class to include binary data inside XML strings using "Base64 encoding".
Definition: xmlParser.h:737
XMLAttribute attrib
Definition: xmlParser.h:654
#define FALSE
Definition: xmlParser.h:196
XMLDLLENTRY char xmltob(XMLCSTR xmlString, char defautValue=0)
Definition: xmlParser.cpp:312
GLuint const GLchar * name
Definition: glext.h:3891
XMLClear clear
Definition: xmlParser.h:656
GLsizei GLsizei GLchar * source
Definition: glext.h:3908
Structure for XML attribute.
Definition: xmlParser.h:254
struct XMLDLLENTRY XMLParserBase64Tool XMLParserBase64Tool
Helper class to include binary data inside XML strings using "Base64 encoding".
static char guessWideCharChars
Definition: xmlParser.cpp:31
XMLCSTR lpszValue
Definition: xmlParser.h:255
enum XMLError error
Definition: xmlParser.h:244
XMLDLLENTRY long xmltol(XMLCSTR xmlString, long defautValue=0)
Definition: xmlParser.cpp:314
GLsizeiptr size
Definition: glext.h:3779
GLenum GLint x
Definition: glext.h:3516
static char removeCommentsInMiddleOfText
Definition: xmlParser.cpp:31
GLubyte GLubyte GLubyte a
Definition: glext.h:5575
GLfloat GLfloat p
Definition: glext.h:5587
XMLCSTR text
Definition: xmlParser.h:655
XMLDLLENTRY void freeXMLString(XMLSTR t)
to free the string allocated inside the "stringDup" function or the "createXMLString" function...
Definition: xmlParser.cpp:28
struct XMLDLLENTRY XMLNode XMLNode
Main Class representing a XML node.
XMLCSTR lpszCloseTag
Definition: xmlParser.h:250
Structure used to obtain error details if the parse fails.
Definition: xmlParser.h:242
XMLDLLENTRY double xmltof(XMLCSTR xmlString, double defautValue=.0)
Definition: xmlParser.cpp:315
XMLDLLENTRY int xmltoi(XMLCSTR xmlString, int defautValue=0)
Definition: xmlParser.cpp:313



Page generated by Doxygen 1.8.14 for MRPT 1.5.7 Git: 5902e14cc Wed Apr 24 15:04:01 2019 +0200 at lun oct 28 01:39:17 CET 2019