| /****************************************************************************/ |
| /*! \mainpage XMLParser library |
| * \section intro_sec Introduction |
| * |
| * This is a basic XML parser written in ANSI C++ for portability. |
| * It works by using recursion and a node tree for breaking |
| * down the elements of an XML document. |
| * |
| * @version V2.41 |
| * @author Frank Vanden Berghen |
| * |
| * The following license terms for the "XMLParser library from Business-Insight" apply to projects |
| * that are in some way related to |
| * the "mcpat project", including applications |
| * using "mcpat project" and tools developed |
| * for enhancing "mcpat project". All other projects |
| * (not related to "mcpat project") have to use the "XMLParser library from Business-Insight" |
| * code under the Aladdin Free Public License (AFPL) |
| * See the file "AFPL-license.txt" for more informations about the AFPL license. |
| * (see http://www.artifex.com/downloads/doc/Public.htm for detailed AFPL terms) |
| * |
| * Redistribution and use of the "XMLParser library from Business-Insight" in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * * Neither the name of Frank Vanden Berghen nor the |
| * names of its contributors may be used to endorse or promote products |
| * derived from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY Business-Insight ``AS IS'' AND ANY |
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| * DISCLAIMED. IN NO EVENT SHALL Business-Insight BE LIABLE FOR ANY |
| * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| * |
| * Copyright (c) 2002, Business-Insight |
| * Copyright (c) 2010-2013 Advanced Micro Devices, Inc. |
| * <a href="http://www.Business-Insight.com">Business-Insight</a> |
| * All rights reserved. |
| * |
| * \section tutorial First Tutorial |
| * You can follow a simple <a href="../../xmlParser.html">Tutorial</a> to know the basics... |
| * |
| * \section usage General usage: How to include the XMLParser library inside your project. |
| * |
| * The library is composed of two files: <a href="../../xmlParser.cpp">xmlParser.cpp</a> and |
| * <a href="../../xmlParser.h">xmlParser.h</a>. These are the ONLY 2 files that you need when |
| * using the library inside your own projects. |
| * |
| * All the functions of the library are documented inside the comments of the file |
| * <a href="../../xmlParser.h">xmlParser.h</a>. These comments can be transformed in |
| * full-fledged HTML documentation using the DOXYGEN software: simply type: "doxygen doxy.cfg" |
| * |
| * By default, the XMLParser library uses (char*) for string representation.To use the (wchar_t*) |
| * version of the library, you need to define the "_UNICODE" preprocessor definition variable |
| * (this is usually done inside your project definition file) (This is done automatically for you |
| * when using Visual Studio). |
| * |
| * \section example Advanced Tutorial and Many Examples of usage. |
| * |
| * Some very small introductory examples are described inside the Tutorial file |
| * <a href="../../xmlParser.html">xmlParser.html</a> |
| * |
| * Some additional small examples are also inside the file <a href="../../xmlTest.cpp">xmlTest.cpp</a> |
| * (for the "char*" version of the library) and inside the file |
| * <a href="../../xmlTestUnicode.cpp">xmlTestUnicode.cpp</a> (for the "wchar_t*" |
| * version of the library). If you have a question, please review these additionnal examples |
| * before sending an e-mail to the author. |
| * |
| * To build the examples: |
| * - linux/unix: type "make" |
| * - solaris: type "make -f makefile.solaris" |
| * - windows: Visual Studio: double-click on xmlParser.dsw |
| * (under Visual Studio .NET, the .dsp and .dsw files will be automatically converted to .vcproj and .sln files) |
| * |
| * In order to build the examples you need some additional files: |
| * - linux/unix: makefile |
| * - solaris: makefile.solaris |
| * - windows: Visual Studio: *.dsp, xmlParser.dsw and also xmlParser.lib and xmlParser.dll |
| * |
| * \section debugging Debugging with the XMLParser library |
| * |
| * \subsection debugwin Debugging under WINDOWS |
| * |
| * Inside Visual C++, the "debug versions" of the memory allocation functions are |
| * very slow: Do not forget to compile in "release mode" to get maximum speed. |
| * When I had to debug a software that was using the XMLParser Library, it was usually |
| * a nightmare because the library was sooOOOoooo slow in debug mode (because of the |
| * slow memory allocations in Debug mode). To solve this |
| * problem, during all the debugging session, I am now using a very fast DLL version of the |
| * XMLParser Library (the DLL is compiled in release mode). Using the DLL version of |
| * the XMLParser Library allows me to have lightening XML parsing speed even in debug! |
| * Other than that, the DLL version is useless: In the release version of my tool, |
| * I always use the normal, ".cpp"-based, XMLParser Library (I simply include the |
| * <a href="../../xmlParser.cpp">xmlParser.cpp</a> and |
| * <a href="../../xmlParser.h">xmlParser.h</a> files into the project). |
| * |
| * The file <a href="../../XMLNodeAutoexp.txt">XMLNodeAutoexp.txt</a> contains some |
| * "tweaks" that improve substancially the display of the content of the XMLNode objects |
| * inside the Visual Studio Debugger. Believe me, once you have seen inside the debugger |
| * the "smooth" display of the XMLNode objects, you cannot live without it anymore! |
| * |
| * \subsection debuglinux Debugging under LINUX/UNIX |
| * |
| * The speed of the debug version of the XMLParser library is tolerable so no extra |
| * work.has been done. |
| * |
| ****************************************************************************/ |
| |
| #ifndef __INCLUDE_XML_NODE__ |
| #define __INCLUDE_XML_NODE__ |
| |
| #include <stdlib.h> |
| |
| #ifdef _UNICODE |
| // If you comment the next "define" line then the library will never "switch to" _UNICODE (wchar_t*) mode (16/32 bits per characters). |
| // This is useful when you get error messages like: |
| // 'XMLNode::openFileHelper' : cannot convert parameter 2 from 'const char [5]' to 'const wchar_t *' |
| // The _XMLWIDECHAR preprocessor variable force the XMLParser library into either utf16/32-mode (the proprocessor variable |
| // must be defined) or utf8-mode(the pre-processor variable must be undefined). |
| #define _XMLWIDECHAR |
| #endif |
| |
| #if defined(WIN32) || defined(UNDER_CE) || defined(_WIN32) || defined(WIN64) || defined(__BORLANDC__) |
| // comment the next line if you are under windows and the compiler is not Microsoft Visual Studio (6.0 or .NET) or Borland |
| #define _XMLWINDOWS |
| #endif |
| |
| #ifdef XMLDLLENTRY |
| #undef XMLDLLENTRY |
| #endif |
| #ifdef _USE_XMLPARSER_DLL |
| #ifdef _DLL_EXPORTS_ |
| #define XMLDLLENTRY __declspec(dllexport) |
| #else |
| #define XMLDLLENTRY __declspec(dllimport) |
| #endif |
| #else |
| #define XMLDLLENTRY |
| #endif |
| |
| // 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) |
| //#define XML_NO_WIDE_CHAR |
| |
| #ifdef XML_NO_WIDE_CHAR |
| #undef _XMLWINDOWS |
| #undef _XMLWIDECHAR |
| #endif |
| |
| #ifdef _XMLWINDOWS |
| #include <tchar.h> |
| #else |
| #define XMLDLLENTRY |
| #ifndef XML_NO_WIDE_CHAR |
| #include <wchar.h> // to have 'wcsrtombs' for ANSI version |
| // to have 'mbsrtowcs' for WIDECHAR version |
| #endif |
| #endif |
| |
| // Some common types for char set portable code |
| #ifdef _XMLWIDECHAR |
| #define _CXML(c) L ## c |
| #define XMLCSTR const wchar_t * |
| #define XMLSTR wchar_t * |
| #define XMLCHAR wchar_t |
| #else |
| #define _CXML(c) c |
| #define XMLCSTR const char * |
| #define XMLSTR char * |
| #define XMLCHAR char |
| #endif |
| #ifndef FALSE |
| #define FALSE 0 |
| #endif /* FALSE */ |
| #ifndef TRUE |
| #define TRUE 1 |
| #endif /* TRUE */ |
| |
| |
| /// Enumeration for XML parse errors. |
| typedef enum XMLError { |
| eXMLErrorNone = 0, |
| eXMLErrorMissingEndTag, |
| eXMLErrorNoXMLTagFound, |
| eXMLErrorEmpty, |
| eXMLErrorMissingTagName, |
| eXMLErrorMissingEndTagName, |
| eXMLErrorUnmatchedEndTag, |
| eXMLErrorUnmatchedEndClearTag, |
| eXMLErrorUnexpectedToken, |
| eXMLErrorNoElements, |
| eXMLErrorFileNotFound, |
| eXMLErrorFirstTagNotFound, |
| eXMLErrorUnknownCharacterEntity, |
| eXMLErrorCharacterCodeAbove255, |
| eXMLErrorCharConversionError, |
| eXMLErrorCannotOpenWriteFile, |
| eXMLErrorCannotWriteFile, |
| |
| eXMLErrorBase64DataSizeIsNotMultipleOf4, |
| eXMLErrorBase64DecodeIllegalCharacter, |
| eXMLErrorBase64DecodeTruncatedData, |
| eXMLErrorBase64DecodeBufferTooSmall |
| } XMLError; |
| |
| |
| /// Enumeration used to manage type of data. Use in conjunction with structure XMLNodeContents |
| typedef enum XMLElementType { |
| eNodeChild = 0, |
| eNodeAttribute = 1, |
| eNodeText = 2, |
| eNodeClear = 3, |
| eNodeNULL = 4 |
| } XMLElementType; |
| |
| /// Structure used to obtain error details if the parse fails. |
| typedef struct XMLResults { |
| enum XMLError error; |
| int nLine; |
| int nColumn; |
| } XMLResults; |
| |
| /// Structure for XML clear (unformatted) node (usually comments) |
| typedef struct XMLClear { |
| XMLCSTR lpszValue; |
| XMLCSTR lpszOpenTag; |
| XMLCSTR lpszCloseTag; |
| } XMLClear; |
| |
| /// Structure for XML attribute. |
| typedef struct XMLAttribute { |
| XMLCSTR lpszName; |
| XMLCSTR lpszValue; |
| } XMLAttribute; |
| |
| /// XMLElementPosition are not interchangeable with simple indexes |
| typedef int XMLElementPosition; |
| |
| struct XMLNodeContents; |
| |
| /** @defgroup XMLParserGeneral The XML parser */ |
| |
| /// Main Class representing a XML node |
| /** |
| * All operations are performed using this class. |
| * \note The constructors of the XMLNode class are protected, so use instead one of these four methods to get your first instance of XMLNode: |
| * <ul> |
| * <li> XMLNode::parseString </li> |
| * <li> XMLNode::parseFile </li> |
| * <li> XMLNode::openFileHelper </li> |
| * <li> XMLNode::createXMLTopNode (or XMLNode::createXMLTopNode_WOSD)</li> |
| * </ul> */ |
| typedef struct XMLDLLENTRY XMLNode { |
| private: |
| |
| struct XMLNodeDataTag; |
| |
| /// Constructors are protected, so use instead one of: XMLNode::parseString, XMLNode::parseFile, XMLNode::openFileHelper, XMLNode::createXMLTopNode |
| XMLNode(struct XMLNodeDataTag *pParent, XMLSTR lpszName, char isDeclaration); |
| /// Constructors are protected, so use instead one of: XMLNode::parseString, XMLNode::parseFile, XMLNode::openFileHelper, XMLNode::createXMLTopNode |
| XMLNode(struct XMLNodeDataTag *p); |
| |
| public: |
| static XMLCSTR getVersion();///< Return the XMLParser library version number |
| |
| /** @defgroup conversions Parsing XML files/strings to an XMLNode structure and Rendering XMLNode's to files/string. |
| * @ingroup XMLParserGeneral |
| * @{ */ |
| |
| /// Parse an XML string and return the root of a XMLNode tree representing the string. |
| static XMLNode parseString(XMLCSTR lpXMLString, XMLCSTR tag = NULL, |
| XMLResults *pResults = NULL); |
| /**< The "parseString" function parse an XML string and return the root of a XMLNode tree. The "opposite" of this function is |
| * the function "createXMLString" that re-creates an XML string from an XMLNode tree. If the XML document is corrupted, the |
| * "parseString" method will initialize the "pResults" variable with some information that can be used to trace the error. |
| * If you still want to parse the file, you can use the APPROXIMATE_PARSING option as explained inside the note at the |
| * beginning of the "xmlParser.cpp" file. |
| * |
| * @param lpXMLString the XML string to parse |
| * @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 (<? ... ?>). |
| * @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. |
| */ |
| |
| /// Parse an XML file and return the root of a XMLNode tree representing the file. |
| static XMLNode parseFile(XMLCSTR filename, XMLCSTR tag = NULL, |
| XMLResults *pResults = NULL); |
| /**< The "parseFile" function parse an XML file and return the root of a XMLNode tree. The "opposite" of this function is |
| * the function "writeToFile" that re-creates an XML file from an XMLNode tree. If the XML document is corrupted, the |
| * "parseFile" method will initialize the "pResults" variable with some information that can be used to trace the error. |
| * If you still want to parse the file, you can use the APPROXIMATE_PARSING option as explained inside the note at the |
| * beginning of the "xmlParser.cpp" file. |
| * |
| * @param filename the path to the XML file to parse |
| * @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 (<? ... ?>). |
| * @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. |
| */ |
| |
| /// 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. |
| static XMLNode openFileHelper(XMLCSTR filename, XMLCSTR tag = NULL); |
| /**< The "openFileHelper" function reports to the screen all the warnings and errors that occurred during parsing of the XML file. |
| * 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 |
| * application has its own way to report and deal with errors, you should rather use the "parseFile" function to parse XML files |
| * and program yourself thereafter an "error reporting" tailored for your needs (instead of using the very crude "error reporting" |
| * mechanism included inside the "openFileHelper" function). |
| * |
| * If the XML document is corrupted, the "openFileHelper" method will: |
| * - display an error message on the console (or inside a messageBox for windows). |
| * - stop execution (exit). |
| * |
| * I strongly suggest that you write your own "openFileHelper" method tailored to your needs. If you still want to parse |
| * the file, you can use the APPROXIMATE_PARSING option as explained inside the note at the beginning of the "xmlParser.cpp" file. |
| * |
| * @param filename the path of the XML file to parse. |
| * @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 (<? ... ?>). |
| */ |
| |
| static XMLCSTR getError(XMLError error); ///< this gives you a user-friendly explanation of the parsing error |
| |
| /// Create an XML string starting from the current XMLNode. |
| XMLSTR createXMLString(int nFormat = 1, int *pnSize = NULL) const; |
| /**< The returned string should be free'd using the "freeXMLString" function. |
| * |
| * 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. if pnSize is given it returns the size in character of the string. */ |
| |
| /// Save the content of an xmlNode inside a file |
| XMLError writeToFile(XMLCSTR filename, |
| const char *encoding = NULL, |
| char nFormat = 1) const; |
| /**< 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. |
| * If the global parameter "characterEncoding==encoding_UTF8", then the "encoding" parameter is ignored and always set to "utf-8". |
| * If the global parameter "characterEncoding==encoding_ShiftJIS", then the "encoding" parameter is ignored and always set to "SHIFT-JIS". |
| * If "_XMLWIDECHAR=1", then the "encoding" parameter is ignored and always set to "utf-16". |
| * If no "encoding" parameter is given the "ISO-8859-1" encoding is used. */ |
| /** @} */ |
| |
| /** @defgroup navigate Navigate the XMLNode structure |
| * @ingroup XMLParserGeneral |
| * @{ */ |
| XMLCSTR getName() const; ///< name of the node |
| XMLCSTR getText(int i=0) const; ///< return ith text field |
| int nText() const; ///< nbr of text field |
| XMLNode getParentNode() const; ///< return the parent node |
| XMLNode getChildNode(int i=0) const; ///< return ith child node |
| 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. |
| XMLNode getChildNode(XMLCSTR name, int *i=NULL) const; ///< return next child node with specific name (return an empty node if failing) |
| XMLNode* getChildNodePtr(XMLCSTR name, int *j) const; |
| XMLNode getChildNodeWithAttribute(XMLCSTR tagName, |
| XMLCSTR attributeName, |
| XMLCSTR attributeValue=NULL, |
| int *i=NULL) const; ///< return child node with specific name/attribute (return an empty node if failing) |
| XMLNode getChildNodeByPath(XMLCSTR path, char createNodeIfMissing=0, XMLCHAR sep='/'); |
| ///< return the first child node with specific path |
| XMLNode getChildNodeByPathNonConst(XMLSTR path, char createNodeIfMissing=0, XMLCHAR sep='/'); |
| ///< return the first child node with specific path. |
| |
| int nChildNode(XMLCSTR name) const; ///< return the number of child node with specific name |
| int nChildNode() const; ///< nbr of child node |
| XMLAttribute getAttribute(int i=0) const; ///< return ith attribute |
| XMLCSTR getAttributeName(int i=0) const; ///< return ith attribute name |
| XMLCSTR getAttributeValue(int i=0) const; ///< return ith attribute value |
| char isAttributeSet(XMLCSTR name) const; ///< test if an attribute with a specific name is given |
| XMLCSTR getAttribute(XMLCSTR name, int i) const; ///< return ith attribute content with specific name (return a NULL if failing) |
| XMLCSTR getAttribute(XMLCSTR name, int *i=NULL) const; ///< return next attribute content with specific name (return a NULL if failing) |
| int nAttribute() const; ///< nbr of attribute |
| XMLClear getClear(int i=0) const; ///< return ith clear field (comments) |
| int nClear() const; ///< nbr of clear field |
| 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(); |
| int nElement() const; ///< nbr of different contents for current node |
| char isEmpty() const; ///< is this node Empty? |
| char isDeclaration() const; ///< is this node a declaration <? .... ?> |
| XMLNode deepCopy() const; ///< deep copy (duplicate/clone) a XMLNode |
| static XMLNode emptyNode(); ///< return XMLNode::emptyXMLNode; |
| /** @} */ |
| |
| ~XMLNode(); |
| XMLNode(const XMLNode &A); ///< to allow shallow/fast copy: |
| XMLNode& operator=( const XMLNode& A ); ///< to allow shallow/fast copy: |
| |
| XMLNode(): d(NULL){}; |
| static XMLNode emptyXMLNode; |
| static XMLClear emptyXMLClear; |
| static XMLAttribute emptyXMLAttribute; |
| |
| /** @defgroup xmlModify Create or Update the XMLNode structure |
| * @ingroup XMLParserGeneral |
| * The functions in this group allows you to create from scratch (or update) a XMLNode structure. Start by creating your top |
| * node with the "createXMLTopNode" function and then add new nodes with the "addChild" function. The parameter 'pos' gives |
| * the position where the childNode, the text or the XMLClearTag will be inserted. The default value (pos=-1) inserts at the |
| * end. The value (pos=0) insert at the beginning (Insertion at the beginning is slower than at the end). <br> |
| * |
| * REMARK: 0 <= pos < nChild()+nText()+nClear() <br> |
| */ |
| |
| /** @defgroup creation Creating from scratch a XMLNode structure |
| * @ingroup xmlModify |
| * @{ */ |
| static XMLNode createXMLTopNode(XMLCSTR lpszName, char isDeclaration=FALSE); ///< Create the top node of an XMLNode structure |
| XMLNode addChild(XMLCSTR lpszName, char isDeclaration=FALSE, XMLElementPosition pos=-1); ///< Add a new child node |
| 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 |
| XMLAttribute *addAttribute(XMLCSTR lpszName, XMLCSTR lpszValuev); ///< Add a new attribute |
| XMLCSTR addText(XMLCSTR lpszValue, XMLElementPosition pos=-1); ///< Add a new text content |
| XMLClear *addClear(XMLCSTR lpszValue, XMLCSTR lpszOpen=NULL, XMLCSTR lpszClose=NULL, XMLElementPosition pos=-1); |
| /**< Add a new clear tag |
| * @param lpszOpen default value "<![CDATA[" |
| * @param lpszClose default value "]]>" |
| */ |
| /** @} */ |
| |
| /** @defgroup xmlUpdate Updating Nodes |
| * @ingroup xmlModify |
| * Some update functions: |
| * @{ |
| */ |
| XMLCSTR updateName(XMLCSTR lpszName); ///< change node's name |
| XMLAttribute *updateAttribute(XMLAttribute *newAttribute, XMLAttribute *oldAttribute); ///< if the attribute to update is missing, a new one will be added |
| XMLAttribute *updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName=NULL, int i=0); ///< if the attribute to update is missing, a new one will be added |
| 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 |
| XMLCSTR updateText(XMLCSTR lpszNewValue, int i=0); ///< if the text to update is missing, a new one will be added |
| XMLCSTR updateText(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue); ///< if the text to update is missing, a new one will be added |
| XMLClear *updateClear(XMLCSTR lpszNewContent, int i=0); ///< if the clearTag to update is missing, a new one will be added |
| XMLClear *updateClear(XMLClear *newP, XMLClear *oldP); ///< if the clearTag to update is missing, a new one will be added |
| XMLClear *updateClear(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue); ///< if the clearTag to update is missing, a new one will be added |
| /** @} */ |
| |
| /** @defgroup xmlDelete Deleting Nodes or Attributes |
| * @ingroup xmlModify |
| * Some deletion functions: |
| * @{ |
| */ |
| /// The "deleteNodeContent" function forces the deletion of the content of this XMLNode and the subtree. |
| void deleteNodeContent(); |
| /**< \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. */ |
| void deleteAttribute(int i=0); ///< Delete the ith attribute of the current XMLNode |
| void deleteAttribute(XMLCSTR lpszName); ///< Delete the attribute with the given name (the "strcmp" function is used to find the right attribute) |
| void deleteAttribute(XMLAttribute *anAttribute); ///< Delete the attribute with the name "anAttribute->lpszName" (the "strcmp" function is used to find the right attribute) |
| void deleteText(int i=0); ///< Delete the Ith text content of the current XMLNode |
| 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) |
| void deleteClear(int i=0); ///< Delete the Ith clear tag inside the current XMLNode |
| 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) |
| 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) |
| /** @} */ |
| |
| /** @defgroup xmlWOSD ???_WOSD functions. |
| * @ingroup xmlModify |
| * The strings given as parameters for the "add" and "update" methods that have a name with |
| * the postfix "_WOSD" (that means "WithOut String Duplication")(for example "addText_WOSD") |
| * will be free'd by the XMLNode class. For example, it means that this is incorrect: |
| * \code |
| * xNode.addText_WOSD("foo"); |
| * xNode.updateAttribute_WOSD("#newcolor" ,NULL,"color"); |
| * \endcode |
| * In opposition, this is correct: |
| * \code |
| * xNode.addText("foo"); |
| * xNode.addText_WOSD(stringDup("foo")); |
| * xNode.updateAttribute("#newcolor" ,NULL,"color"); |
| * xNode.updateAttribute_WOSD(stringDup("#newcolor"),NULL,"color"); |
| * \endcode |
| * Typically, you will never do: |
| * \code |
| * char *b=(char*)malloc(...); |
| * xNode.addText(b); |
| * free(b); |
| * \endcode |
| * ... but rather: |
| * \code |
| * char *b=(char*)malloc(...); |
| * xNode.addText_WOSD(b); |
| * \endcode |
| * ('free(b)' is performed by the XMLNode class) |
| * @{ */ |
| static XMLNode createXMLTopNode_WOSD(XMLSTR lpszName, char isDeclaration=FALSE); ///< Create the top node of an XMLNode structure |
| XMLNode addChild_WOSD(XMLSTR lpszName, char isDeclaration=FALSE, XMLElementPosition pos=-1); ///< Add a new child node |
| XMLAttribute *addAttribute_WOSD(XMLSTR lpszName, XMLSTR lpszValue); ///< Add a new attribute |
| XMLCSTR addText_WOSD(XMLSTR lpszValue, XMLElementPosition pos=-1); ///< Add a new text content |
| XMLClear *addClear_WOSD(XMLSTR lpszValue, XMLCSTR lpszOpen=NULL, XMLCSTR lpszClose=NULL, XMLElementPosition pos=-1); ///< Add a new clear Tag |
| |
| XMLCSTR updateName_WOSD(XMLSTR lpszName); ///< change node's name |
| XMLAttribute *updateAttribute_WOSD(XMLAttribute *newAttribute, XMLAttribute *oldAttribute); ///< if the attribute to update is missing, a new one will be added |
| XMLAttribute *updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName=NULL, int i=0); ///< if the attribute to update is missing, a new one will be added |
| 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 |
| XMLCSTR updateText_WOSD(XMLSTR lpszNewValue, int i=0); ///< if the text to update is missing, a new one will be added |
| XMLCSTR updateText_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue); ///< if the text to update is missing, a new one will be added |
| XMLClear *updateClear_WOSD(XMLSTR lpszNewContent, int i=0); ///< if the clearTag to update is missing, a new one will be added |
| XMLClear *updateClear_WOSD(XMLClear *newP, XMLClear *oldP); ///< if the clearTag to update is missing, a new one will be added |
| XMLClear *updateClear_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue); ///< if the clearTag to update is missing, a new one will be added |
| /** @} */ |
| |
| /** @defgroup xmlPosition Position helper functions (use in conjunction with the update&add functions |
| * @ingroup xmlModify |
| * These are some useful functions when you want to insert a childNode, a text or a XMLClearTag in the |
| * middle (at a specified position) of a XMLNode tree already constructed. The value returned by these |
| * methods is to be used as last parameter (parameter 'pos') of addChild, addText or addClear. |
| * @{ */ |
| XMLElementPosition positionOfText(int i=0) const; |
| XMLElementPosition positionOfText(XMLCSTR lpszValue) const; |
| XMLElementPosition positionOfClear(int i=0) const; |
| XMLElementPosition positionOfClear(XMLCSTR lpszValue) const; |
| XMLElementPosition positionOfClear(XMLClear *a) const; |
| XMLElementPosition positionOfChildNode(int i=0) const; |
| XMLElementPosition positionOfChildNode(XMLNode x) const; |
| 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 |
| /** @} */ |
| |
| /// Enumeration for XML character encoding. |
| typedef enum XMLCharEncoding { |
| char_encoding_error = 0, |
| char_encoding_UTF8 = 1, |
| char_encoding_legacy = 2, |
| char_encoding_ShiftJIS = 3, |
| char_encoding_GB2312 = 4, |
| char_encoding_Big5 = 5, |
| char_encoding_GBK = 6 // this is actually the same as Big5 |
| } XMLCharEncoding; |
| |
| /** \addtogroup conversions |
| * @{ */ |
| |
| /// Sets the global options for the conversions |
| static char setGlobalOptions(XMLCharEncoding characterEncoding=XMLNode::char_encoding_UTF8, char guessWideCharChars=1, |
| char dropWhiteSpace=1, char removeCommentsInMiddleOfText=1); |
| /**< The "setGlobalOptions" function allows you to change four global parameters that affect string & file |
| * parsing. First of all, you most-probably will never have to change these 3 global parameters. |
| * |
| * @param guessWideCharChars If "guessWideCharChars"=1 and if this library is compiled in WideChar mode, then the |
| * XMLNode::parseFile and XMLNode::openFileHelper functions will test if the file contains ASCII |
| * characters. If this is the case, then the file will be loaded and converted in memory to |
| * WideChar before being parsed. If 0, no conversion will be performed. |
| * |
| * @param guessWideCharChars If "guessWideCharChars"=1 and if this library is compiled in ASCII/UTF8/char* mode, then the |
| * XMLNode::parseFile and XMLNode::openFileHelper functions will test if the file contains WideChar |
| * characters. If this is the case, then the file will be loaded and converted in memory to |
| * ASCII/UTF8/char* before being parsed. If 0, no conversion will be performed. |
| * |
| * @param characterEncoding This parameter is only meaningful when compiling in char* mode (multibyte character mode). |
| * In wchar_t* (wide char mode), this parameter is ignored. This parameter should be one of the |
| * three currently recognized encodings: XMLNode::encoding_UTF8, XMLNode::encoding_ascii, |
| * XMLNode::encoding_ShiftJIS. |
| * |
| * @param dropWhiteSpace In most situations, text fields containing only white spaces (and carriage returns) |
| * are useless. Even more, these "empty" text fields are annoying because they increase the |
| * complexity of the user's code for parsing. So, 99% of the time, it's better to drop |
| * the "empty" text fields. However The XML specification indicates that no white spaces |
| * should be lost when parsing the file. So to be perfectly XML-compliant, you should set |
| * dropWhiteSpace=0. A note of caution: if you set "dropWhiteSpace=0", the parser will be |
| * slower and your code will be more complex. |
| * |
| * @param removeCommentsInMiddleOfText To explain this parameter, let's consider this code: |
| * \code |
| * XMLNode x=XMLNode::parseString("<a>foo<!-- hello -->bar<!DOCTYPE world >chu</a>","a"); |
| * \endcode |
| * If removeCommentsInMiddleOfText=0, then we will have: |
| * \code |
| * x.getText(0) -> "foo" |
| * x.getText(1) -> "bar" |
| * x.getText(2) -> "chu" |
| * x.getClear(0) --> "<!-- hello -->" |
| * x.getClear(1) --> "<!DOCTYPE world >" |
| * \endcode |
| * If removeCommentsInMiddleOfText=1, then we will have: |
| * \code |
| * x.getText(0) -> "foobar" |
| * x.getText(1) -> "chu" |
| * x.getClear(0) --> "<!DOCTYPE world >" |
| * \endcode |
| * |
| * \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. |
| * |
| * \note Sometime, it's useful to set "guessWideCharChars=0" to disable any conversion |
| * because the test to detect the file-type (ASCII/UTF8/char* or WideChar) may fail (rarely). */ |
| |
| /// Guess the character encoding of the string (ascii, utf8 or shift-JIS) |
| static XMLCharEncoding guessCharEncoding(void *buffer, int bufLen, char useXMLEncodingAttribute=1); |
| /**< The "guessCharEncoding" function try to guess the character encoding. You most-probably will never |
| * have to use this function. It then returns the appropriate value of the global parameter |
| * "characterEncoding" described in the XMLNode::setGlobalOptions. The guess is based on the content of a buffer of length |
| * "bufLen" bytes that contains the first bytes (minimum 25 bytes; 200 bytes is a good value) of the |
| * file to be parsed. The XMLNode::openFileHelper function is using this function to automatically compute |
| * the value of the "characterEncoding" global parameter. There are several heuristics used to do the |
| * guess. One of the heuristic is based on the "encoding" attribute. The original XML specifications |
| * forbids to use this attribute to do the guess but you can still use it if you set |
| * "useXMLEncodingAttribute" to 1 (this is the default behavior and the behavior of most parsers). |
| * If an inconsistency in the encoding is detected, then the return value is "0". */ |
| /** @} */ |
| |
| private: |
| // these are functions and structures used internally by the XMLNode class (don't bother about them): |
| |
| typedef struct XMLNodeDataTag { // to allow shallow copy and "intelligent/smart" pointers (automatic delete): |
| XMLCSTR lpszName; // Element name (=NULL if root) |
| int nChild, // Number of child nodes |
| nText, // Number of text fields |
| nClear, // Number of Clear fields (comments) |
| nAttribute; // Number of attributes |
| char isDeclaration; // Whether node is an XML declaration - '<?xml ?>' |
| struct XMLNodeDataTag *pParent; // Pointer to parent element (=NULL if root) |
| XMLNode *pChild; // Array of child nodes |
| XMLCSTR *pText; // Array of text fields |
| XMLClear *pClear; // Array of clear fields |
| XMLAttribute *pAttribute; // Array of attributes |
| int *pOrder; // order of the child_nodes,text_fields,clear_fields |
| int ref_count; // for garbage collection (smart pointers) |
| } XMLNodeData; |
| XMLNodeData *d; |
| |
| char parseClearTag(void *px, void *pa); |
| char maybeAddTxT(void *pa, XMLCSTR tokenPStr); |
| int ParseXMLElement(void *pXML); |
| void *addToOrder(int memInc, int *_pos, int nc, void *p, int size, XMLElementType xtype); |
| int indexText(XMLCSTR lpszValue) const; |
| int indexClear(XMLCSTR lpszValue) const; |
| XMLNode addChild_priv(int, XMLSTR, char, int); |
| XMLAttribute *addAttribute_priv(int, XMLSTR, XMLSTR); |
| XMLCSTR addText_priv(int, XMLSTR, int); |
| XMLClear *addClear_priv(int, XMLSTR, XMLCSTR, XMLCSTR, int); |
| void emptyTheNode(char force); |
| static inline XMLElementPosition findPosition(XMLNodeData *d, int index, XMLElementType xtype); |
| static int CreateXMLStringR(XMLNodeData *pEntry, XMLSTR lpszMarker, int nFormat); |
| static int removeOrderElement(XMLNodeData *d, XMLElementType t, int index); |
| static void exactMemory(XMLNodeData *d); |
| static int detachFromParent(XMLNodeData *d); |
| } XMLNode; |
| |
| /// This structure is given by the function XMLNode::enumContents. |
| typedef struct XMLNodeContents { |
| /// This dictates what's the content of the XMLNodeContent |
| enum XMLElementType etype; |
| /**< should be an union to access the appropriate data. Compiler does not allow union of object with constructor... too bad. */ |
| XMLNode child; |
| XMLAttribute attrib; |
| XMLCSTR text; |
| XMLClear clear; |
| |
| } XMLNodeContents; |
| |
| /** @defgroup StringAlloc String Allocation/Free functions |
| * @ingroup xmlModify |
| * @{ */ |
| /// Duplicate (copy in a new allocated buffer) the source string. |
| XMLDLLENTRY XMLSTR stringDup(XMLCSTR source, int cbData=-1); |
| /**< This is |
| * a very handy function when used with all the "XMLNode::*_WOSD" functions (\link xmlWOSD \endlink). |
| * @param cbData If !=0 then cbData is the number of chars to duplicate. New strings allocated with |
| * this function should be free'd using the "freeXMLString" function. */ |
| |
| /// to free the string allocated inside the "stringDup" function or the "createXMLString" function. |
| XMLDLLENTRY void freeXMLString(XMLSTR t); // {free(t);} |
| /** @} */ |
| |
| /** @defgroup atoX ato? like functions |
| * @ingroup XMLParserGeneral |
| * The "xmlto?" functions are equivalents to the atoi, atol, atof functions. |
| * The only difference is: If the variable "xmlString" is NULL, than the return value |
| * is "defautValue". These 6 functions are only here as "convenience" functions for the |
| * user (they are not used inside the XMLparser). If you don't need them, you can |
| * delete them without any trouble. |
| * |
| * @{ */ |
| XMLDLLENTRY char xmltob(XMLCSTR xmlString, char defautValue=0); |
| XMLDLLENTRY int xmltoi(XMLCSTR xmlString, int defautValue=0); |
| XMLDLLENTRY long xmltol(XMLCSTR xmlString, long defautValue=0); |
| XMLDLLENTRY double xmltof(XMLCSTR xmlString, double defautValue=.0); |
| XMLDLLENTRY XMLCSTR xmltoa(XMLCSTR xmlString, XMLCSTR defautValue=_CXML("")); |
| XMLDLLENTRY XMLCHAR xmltoc(XMLCSTR xmlString, XMLCHAR defautValue=_CXML('\0')); |
| /** @} */ |
| |
| /** @defgroup ToXMLStringTool Helper class to create XML files using "printf", "fprintf", "cout",... functions. |
| * @ingroup XMLParserGeneral |
| * @{ */ |
| /// Helper class to create XML files using "printf", "fprintf", "cout",... functions. |
| /** The ToXMLStringTool class helps you creating XML files using "printf", "fprintf", "cout",... functions. |
| * The "ToXMLStringTool" class is processing strings so that all the characters |
| * &,",',<,> are replaced by their XML equivalent: |
| * \verbatim &, ", ', <, > \endverbatim |
| * Using the "ToXMLStringTool class" and the "fprintf function" is THE most efficient |
| * way to produce VERY large XML documents VERY fast. |
| * \note If you are creating from scratch an XML file using the provided XMLNode class |
| * you must not use the "ToXMLStringTool" class (because the "XMLNode" class does the |
| * processing job for you during rendering).*/ |
| typedef struct XMLDLLENTRY ToXMLStringTool { |
| public: |
| ToXMLStringTool(): buf(NULL), buflen(0){} |
| ~ToXMLStringTool(); |
| void freeBuffer();///<call this function when you have finished using this object to release memory used by the internal buffer. |
| |
| XMLSTR toXML(XMLCSTR source);///< returns a pointer to an internal buffer that contains a XML-encoded string based on the "source" parameter. |
| |
| /** The "toXMLUnSafe" function is deprecated because there is a possibility of |
| * "destination-buffer-overflow". It converts the string |
| * "source" to the string "dest". */ |
| static XMLSTR toXMLUnSafe(XMLSTR dest,XMLCSTR source); ///< deprecated: use "toXML" instead |
| static int lengthXMLString(XMLCSTR source); ///< deprecated: use "toXML" instead |
| |
| private: |
| XMLSTR buf; |
| int buflen; |
| } ToXMLStringTool; |
| /** @} */ |
| |
| /** @defgroup XMLParserBase64Tool Helper class to include binary data inside XML strings using "Base64 encoding". |
| * @ingroup XMLParserGeneral |
| * @{ */ |
| /// Helper class to include binary data inside XML strings using "Base64 encoding". |
| /** The "XMLParserBase64Tool" class allows you to include any binary data (images, sounds,...) |
| * into an XML document using "Base64 encoding". This class is completely |
| * separated from the rest of the xmlParser library and can be removed without any problem. |
| * To include some binary data into an XML file, you must convert the binary data into |
| * standard text (using "encode"). To retrieve the original binary data from the |
| * b64-encoded text included inside the XML file, use "decode". Alternatively, these |
| * functions can also be used to "encrypt/decrypt" some critical data contained inside |
| * the XML (it's not a strong encryption at all, but sometimes it can be useful). */ |
| typedef struct XMLDLLENTRY XMLParserBase64Tool { |
| public: |
| XMLParserBase64Tool(): buf(NULL), buflen(0){} |
| ~XMLParserBase64Tool(); |
| void freeBuffer();///< Call this function when you have finished using this object to release memory used by the internal buffer. |
| |
| /** |
| * @param formatted If "formatted"=true, some space will be reserved for a carriage-return every 72 chars. */ |
| static int encodeLength(int inBufLen, char formatted=0); ///< return the length of the base64 string that encodes a data buffer of size inBufLen bytes. |
| |
| /** |
| * The "base64Encode" function returns a string containing the base64 encoding of "inByteLen" bytes |
| * from "inByteBuf". If "formatted" parameter is true, then there will be a carriage-return every 72 chars. |
| * The string will be free'd when the XMLParserBase64Tool object is deleted. |
| * All returned strings are sharing the same memory space. */ |
| 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" |
| |
| /// returns the number of bytes which will be decoded from "inString". |
| static unsigned int decodeSize(XMLCSTR inString, XMLError *xe=NULL); |
| |
| /** |
| * The "decode" function returns a pointer to a buffer containing the binary data decoded from "inString" |
| * The output buffer will be free'd when the XMLParserBase64Tool object is deleted. |
| * All output buffer are sharing the same memory space. |
| * @param inString If "instring" is malformed, NULL will be returned */ |
| 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" |
| |
| /** |
| * decodes data from "inString" to "outByteBuf". You need to provide the size (in byte) of "outByteBuf" |
| * in "inMaxByteOutBuflen". If "outByteBuf" is not large enough or if data is malformed, then "FALSE" |
| * will be returned; otherwise "TRUE". */ |
| static unsigned char decode(XMLCSTR inString, unsigned char *outByteBuf, int inMaxByteOutBuflen, XMLError *xe=NULL); ///< deprecated. |
| |
| private: |
| void *buf; |
| int buflen; |
| void alloc(int newsize); |
| }XMLParserBase64Tool; |
| /** @} */ |
| |
| #undef XMLDLLENTRY |
| |
| #endif |