00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00045
00046 #ifndef CPPDOM_CPPDOM_H
00047 #define CPPDOM_CPPDOM_H
00048
00049 #ifdef _MSC_VER
00050
00051 # pragma warning(disable: 4786)
00052
00053
00054 # if _MSC_VER < 1300
00055 # define CPPDOM_NO_MEMBER_TEMPLATES
00056 # endif
00057 #endif
00058
00059
00060 #include <string>
00061 #include <sstream>
00062 #include <list>
00063 #include <map>
00064 #include <iosfwd>
00065 #include <fstream>
00066 #include <iostream>
00067 #include "config.h"
00068 #include "shared_ptr.h"
00069
00071 namespace cppdom
00072 {
00074 enum XMLErrorCode
00075 {
00076 xml_unknown = 0,
00077 xml_instream_error,
00078 xml_opentag_expected,
00079 xml_opentag_cdata_expected,
00080 xml_closetag_expected,
00081 xml_pi_doctype_expected,
00082 xml_tagname_expected,
00083 xml_closetag_slash_expected,
00084 xml_tagname_close_mismatch,
00085 xml_attr_equal_expected,
00086 xml_attr_value_expected,
00087 xml_save_invalid_nodetype,
00089
00090 xml_filename_invalid,
00091 xml_file_access,
00092
00093 xml_dummy
00094 };
00095
00096
00097
00098
00103 class CPPDOM_API XMLError
00104 {
00105 public:
00107 XMLError(XMLErrorCode code);
00108
00110 XMLErrorCode getError() const;
00111
00113 void getStrError(std::string& error) const;
00114
00115 std::string getString() const;
00116
00118 std::string getInfo() const;
00119
00120 protected:
00121 XMLErrorCode mErrorCode;
00122 };
00123
00124
00130 class CPPDOM_API XMLLocation
00131 {
00132 public:
00134 XMLLocation();
00135
00137 int getLine() const;
00138
00140 int getPos() const;
00141
00143 void step(int chars = 1);
00144
00146 void newline();
00147
00149 void reset();
00150
00151 protected:
00152 int mLine;
00153 int mPos;
00154 };
00155
00156
00157
00158
00160 typedef int XMLTagNameHandle;
00162 typedef std::map<XMLTagNameHandle,std::string> XMLTagNameMap;
00164 typedef std::map<std::string,std::string> XMLEntityMap;
00166 typedef cppdom_boost::shared_ptr<class XMLContext> XMLContextPtr;
00168 typedef cppdom_boost::shared_ptr<class XMLEventHandler> XMLEventHandlerPtr;
00169
00175 class CPPDOM_API XMLContext
00176 {
00177 public:
00179 XMLContext();
00181 virtual ~XMLContext();
00182
00184 std::string getEntity(const std::string& entname);
00185
00187 std::string getTagname(XMLTagNameHandle handle);
00188
00190 XMLTagNameHandle insertTagname(const std::string& tagname);
00191
00193 XMLLocation& getLocation();
00194
00198 virtual void initContext();
00199
00203 void setEventHandler(XMLEventHandlerPtr ehptr);
00204
00206 XMLEventHandler& getEventHandler();
00207
00209 bool handleEvents() const;
00211
00212 protected:
00213 bool mInit;
00214 int mNextHandle;
00215 XMLTagNameMap mTagNames;
00216 XMLEntityMap mEntities;
00217 XMLLocation mLocation;
00218 bool mHandleEvents;
00219 XMLEventHandlerPtr mEventHandler;
00220 };
00221
00223 enum XMLNodeType
00224 {
00225 xml_nt_node,
00226 xml_nt_leaf,
00227 xml_nt_document,
00228 xml_nt_cdata
00229 };
00230
00231
00232
00234 typedef cppdom_boost::shared_ptr<class XMLNode> XMLNodePtr;
00235
00237 typedef std::list<XMLNodePtr> XMLNodeList;
00238 typedef XMLNodeList::iterator XMLNodeListIterator;
00239
00240
00241
00246 class CPPDOM_API XMLAttribute
00247 {
00248 public:
00249 XMLAttribute();
00250 XMLAttribute(const XMLAttribute& attr);
00251 XMLAttribute(const std::string& val);
00252
00253 #ifndef CPPDOM_NO_MEMBER_TEMPLATES
00254 template<class T>
00255 XMLAttribute(const T& val)
00256 {
00257 setValue<T>(val);
00258 }
00259 #endif // ! CPPDOM_NO_MEMBER_TEMPLATES
00260
00261 const std::string& getString() const;
00262
00263 #ifndef CPPDOM_NO_MEMBER_TEMPLATES
00264
00268 template<class T>
00269 void setValue(const T& val)
00270 {
00271 std::ostringstream oss;
00272 oss << val;
00273 mData = oss.str();
00274 }
00275
00276 template<class T>
00277 T getValue() const
00278 {
00279 T t;
00280 std::istringstream iss(mData);
00281 iss >> t;
00282 return t;
00283 }
00284
00285
00286
00287
00288 #ifdef _MSC_VER
00289
00293 template<>
00294 std::string getValue<std::string>() const
00295 {
00296 std::string value(mData);
00297 return value;
00298 }
00299 #endif // ! _MSC_VER
00300 #endif // ! CPPDOM_NO_MEMBER_TEMPLATES
00301
00303 operator std::string() const;
00304
00305 protected:
00306 std::string mData;
00307 };
00308
00309 #ifndef CPPDOM_NO_MEMBER_TEMPLATES
00310 #ifndef _MSC_VER
00311 template<>
00312 inline std::string XMLAttribute::getValue<std::string>() const
00313 {
00314 std::string value(mData);
00315 return value;
00316 }
00317 #endif // ! _MSC_VER
00318 #endif // ! CPPDOM_NO_MEMBER_TEMPLATES
00319
00320
00325 class CPPDOM_API XMLAttributes: public std::map<std::string, std::string>
00326 {
00327 friend class XMLParser;
00328 public:
00330 XMLAttributes();
00331
00336 std::string get(const std::string& key) const;
00337
00342 void set(const std::string& key, const std::string& value);
00343
00348 bool has(const std::string& key) const;
00349 };
00350
00351
00352
00353
00362 class CPPDOM_API XMLNode
00363 {
00364 friend class XMLParser;
00365 protected:
00367 XMLNode();
00368
00369 public:
00371 explicit XMLNode(XMLContextPtr pctx);
00372
00373 XMLNode(const XMLNode& node);
00374 ~XMLNode();
00375
00377 XMLNode& operator=(const XMLNode& node);
00378
00382 XMLNodeType getType() const;
00383
00385 std::string getName();
00386
00388 XMLAttributes& getAttrMap();
00389
00395 XMLAttribute getAttribute(const std::string& name) const;
00396
00398 bool hasAttribute(const std::string& name) const;
00399
00405 const std::string& getCdata();
00407
00411 void setType(XMLNodeType type);
00412
00414 void setName(const std::string& name);
00415
00417 void setCdata(const std::string& cdata);
00418
00423 void setAttribute(const std::string& attr, const XMLAttribute& value);
00424
00425 void addChild(XMLNodePtr& node);
00426 bool removeChild(XMLNodePtr& node);
00427 bool removeChild(std::string& childName);
00428 bool removeChildren(std::string& childName);
00430
00433
00435 XMLNodeList& getChildren();
00436
00438 XMLNodePtr getChild(const std::string& name);
00439
00445 XMLNodeList getChildren(const std::string& name);
00446
00452 XMLNodeList getChildren(const char* name);
00453
00455 template<class Predicate>
00456 XMLNodeList getChildrenPred(Predicate pred)
00457 {
00458 XMLNodeList result(0);
00459 XMLNodeList::const_iterator iter;
00460
00461
00462 for(iter = mNodeList.begin(); iter != mNodeList.end(); ++iter)
00463 {
00464 if (pred(*iter))
00465 {
00466 result.push_back(*iter);
00467 }
00468 }
00469 return result;
00470 }
00471
00477 XMLNode* getParent() const;
00479
00483 void load(std::istream& in, XMLContextPtr& context);
00484
00486 void save(std::ostream& out, int indent=0);
00488
00489 XMLContextPtr getContext();
00490
00491 protected:
00492 XMLTagNameHandle mNodeNameHandle;
00493 XMLContextPtr mContext;
00494 XMLNodeType mNodeType;
00495 XMLAttributes mAttributes;
00496 std::string mCdata;
00497 XMLNodeList mNodeList;
00498 XMLNode* mParent;
00499 };
00500
00501
00503 class CPPDOM_API XMLDocument: public XMLNode
00504 {
00505 friend class XMLParser;
00506 public:
00507 XMLDocument();
00508
00510 explicit XMLDocument(XMLContextPtr context);
00511
00513 XMLNodeList& getPiList();
00514
00516 XMLNodeList& getDtdList();
00517
00519 void load(std::istream& in, XMLContextPtr& context);
00520
00522 void save(std::ostream& out);
00523
00527 void loadFile(const std::string& filename) throw(XMLError);
00528
00529 void saveFile(const std::string& filename);
00530
00531
00532 protected:
00534 XMLNodeList mProcInstructions;
00535
00537 XMLNodeList mDtdRules;
00538 };
00539
00540 typedef cppdom_boost::shared_ptr<class XMLDocument> XMLDocumentPtr;
00541
00542
00544 class CPPDOM_API XMLEventHandler
00545 {
00546 public:
00548 XMLEventHandler() {}
00549
00551 virtual ~XMLEventHandler() {}
00552
00554 virtual void startDocument() {}
00555
00557 virtual void endDocument() {}
00558
00560 virtual void processingInstruction(XMLNode& pinode) {}
00561
00563 virtual void startNode(const std::string& nodename) {}
00565 virtual void parsedAttributes(XMLAttributes& attr) {}
00567 virtual void endNode(XMLNode& node) {}
00568
00570 virtual void gotCdata(const std::string& cdata) {}
00571 };
00572 }
00573
00574 #endif