Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

pxml.h

Go to the documentation of this file.
00001 /* 00002 * pxml.h 00003 * 00004 * XML parser support 00005 * 00006 * Portable Windows Library 00007 * 00008 * Copyright (c) 2002 Equivalence Pty. Ltd. 00009 * 00010 * The contents of this file are subject to the Mozilla Public License 00011 * Version 1.0 (the "License"); you may not use this file except in 00012 * compliance with the License. You may obtain a copy of the License at 00013 * http://www.mozilla.org/MPL/ 00014 * 00015 * Software distributed under the License is distributed on an "AS IS" 00016 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 00017 * the License for the specific language governing rights and limitations 00018 * under the License. 00019 * 00020 * The Original Code is Portable Windows Library. 00021 * 00022 * The Initial Developer of the Original Code is Equivalence Pty. Ltd. 00023 * 00024 * Contributor(s): ______________________________________. 00025 * 00026 * $Log: pxml.h,v $ 00027 * Revision 1.23 2004/04/21 00:35:02 csoutheren 00028 * Added a stream parser for protocols like XMPP where each child of the root is to be considered a separate document/message. 00029 * Thanks to Federico Pinna and Reitek S.p.A. 00030 * 00031 * Revision 1.22 2003/04/27 23:54:13 craigs 00032 * Removed deprecated options 00033 * 00034 * Revision 1.21 2003/03/31 07:41:50 craigs 00035 * Fixed problem with accidental introduced dependency on expat.h 00036 * 00037 * Revision 1.20 2003/03/31 06:21:19 craigs 00038 * Split the expat wrapper from the XML file handling to allow reuse of the parser 00039 * 00040 * Revision 1.19 2003/01/13 02:14:02 robertj 00041 * Improved error logging for auto-loaded XML 00042 * 00043 * Revision 1.18 2002/12/16 06:38:24 robertj 00044 * Added ability to specify certain elemets (by name) that are exempt from 00045 * the indent formatting. Useful for XML/RPC where leading white space is 00046 * not ignored by all servers. 00047 * 00048 * Revision 1.17 2002/11/26 05:53:57 craigs 00049 * Added ability to auto-reload from URL 00050 * 00051 * Revision 1.16 2002/11/21 08:09:04 craigs 00052 * Changed to not overwrite XML data if load fails 00053 * 00054 * Revision 1.15 2002/11/19 07:37:38 craigs 00055 * Added locking functions and LoadURL function 00056 * 00057 * Revision 1.14 2002/11/06 22:47:24 robertj 00058 * Fixed header comment (copyright etc) 00059 * 00060 */ 00061 00062 #ifndef _PXML_H 00063 #define _PXML_H 00064 00065 #ifdef P_USE_PRAGMA 00066 #pragma interface 00067 #endif 00068 00069 #include <ptlib.h> 00070 #include <ptclib/http.h> 00071 00073 00074 class PXMLElement; 00075 class PXMLData; 00076 00077 class PXMLParser : public PObject 00078 { 00079 PCLASSINFO(PXMLParser, PObject); 00080 public: 00081 enum Options { 00082 Indent = 1, 00083 NewLineAfterElement = 2, 00084 NoIgnoreWhiteSpace = 4, // ignored 00085 CloseExtended = 8, // ignored 00086 WithNS = 16, 00087 }; 00088 00089 PXMLParser(int options = -1); 00090 ~PXMLParser(); 00091 BOOL Parse(const char * data, int dataLen, BOOL final); 00092 void GetErrorInfo(PString & errorString, PINDEX & errorCol, PINDEX & errorLine); 00093 00094 virtual void StartElement(const char * name, const char **attrs); 00095 virtual void EndElement(const char * name); 00096 virtual void AddCharacterData(const char * data, int len); 00097 virtual void XmlDecl(const char * version, const char * encoding, int standAlone); 00098 virtual void StartDocTypeDecl(const char * docTypeName, 00099 const char * sysid, 00100 const char * pubid, 00101 int hasInternalSubSet); 00102 virtual void EndDocTypeDecl(); 00103 virtual void StartNamespaceDeclHandler(const char * prefix, const char * uri); 00104 virtual void EndNamespaceDeclHandler(const char * prefix); 00105 00106 PString GetVersion() const { return version; } 00107 PString GetEncoding() const { return encoding; } 00108 BOOL GetStandAlone() const { return standAlone; } 00109 00110 PXMLElement * GetXMLTree() const; 00111 PXMLElement * SetXMLTree(PXMLElement * newRoot); 00112 00113 protected: 00114 int options; 00115 void * expat; 00116 PXMLElement * rootElement; 00117 PXMLElement * currentElement; 00118 PXMLData * lastElement; 00119 PString version, encoding; 00120 int standAlone; 00121 }; 00122 00123 class PXMLObject; 00124 class PXMLElement; 00125 class PXMLData; 00126 00128 00129 class PXMLBase : public PObject 00130 { 00131 public: 00132 PXMLBase(int _options = -1) 00133 : options(_options) { if (options < 0) options = 0; } 00134 00135 void SetOptions(int _options) 00136 { options = _options; } 00137 00138 int GetOptions() const { return options; } 00139 00140 virtual BOOL IsNoIndentElement( 00141 const PString & /*elementName*/ 00142 ) const 00143 { 00144 return FALSE; 00145 } 00146 00147 protected: 00148 int options; 00149 }; 00150 00151 00152 class PXML : public PXMLBase 00153 { 00154 PCLASSINFO(PXML, PObject); 00155 public: 00156 00157 PXML( 00158 int options = -1, 00159 const char * noIndentElements = NULL 00160 ); 00161 PXML( 00162 const PString & data, 00163 int options = -1, 00164 const char * noIndentElements = NULL 00165 ); 00166 00167 PXML(const PXML & xml); 00168 00169 ~PXML(); 00170 00171 BOOL IsDirty() const; 00172 00173 BOOL Load(const PString & data, int options = -1); 00174 00175 BOOL StartAutoReloadURL(const PURL & url, 00176 const PTimeInterval & timeout, 00177 const PTimeInterval & refreshTime, 00178 int _options = -1); 00179 BOOL StopAutoReloadURL(); 00180 PString GetAutoReloadStatus() { PWaitAndSignal m(autoLoadMutex); PString str = autoLoadError; return str; } 00181 BOOL AutoLoadURL(); 00182 virtual void OnAutoLoad(BOOL ok); 00183 00184 BOOL LoadURL(const PURL & url); 00185 BOOL LoadURL(const PURL & url, const PTimeInterval & timeout, int _options = -1); 00186 BOOL LoadFile(const PFilePath & fn, int options = -1); 00187 00188 virtual void OnLoaded() { } 00189 00190 BOOL Save(int options = -1); 00191 BOOL Save(PString & data, int options = -1); 00192 BOOL SaveFile(const PFilePath & fn, int options = -1); 00193 00194 void RemoveAll(); 00195 00196 BOOL IsNoIndentElement( 00197 const PString & elementName 00198 ) const; 00199 00200 void PrintOn(ostream & strm) const; 00201 00202 PXMLElement * GetElement(const PCaselessString & name, PINDEX idx = 0) const; 00203 PXMLElement * GetElement(PINDEX idx) const; 00204 PINDEX GetNumElements() const; 00205 PXMLElement * GetRootElement() const { return rootElement; } 00206 PXMLElement * SetRootElement(PXMLElement * p); 00207 PXMLElement * SetRootElement(const PString & documentType); 00208 BOOL RemoveElement(PINDEX idx); 00209 00210 PCaselessString GetDocumentType() const; 00211 00212 PString GetErrorString() const { return errorString; } 00213 PINDEX GetErrorColumn() const { return errorCol; } 00214 PINDEX GetErrorLine() const { return errorLine; } 00215 00216 PMutex & GetMutex() { return rootMutex; } 00217 00218 PDECLARE_NOTIFIER(PTimer, PXML, AutoReloadTimeout); 00219 PDECLARE_NOTIFIER(PThread, PXML, AutoReloadThread); 00220 00221 // static methods to create XML tags 00222 static PString CreateStartTag (const PString & text); 00223 static PString CreateEndTag (const PString & text); 00224 static PString CreateTagNoData (const PString & text); 00225 static PString CreateTag (const PString & text, const PString & data); 00226 00227 protected: 00228 void Construct(int options, const char * noIndentElements); 00229 PXMLElement * rootElement; 00230 PMutex rootMutex; 00231 00232 BOOL loadFromFile; 00233 PFilePath loadFilename; 00234 PString version, encoding; 00235 int standAlone; 00236 00237 PTimer autoLoadTimer; 00238 PURL autoloadURL; 00239 PTimeInterval autoLoadWaitTime; 00240 PMutex autoLoadMutex; 00241 PString autoLoadError; 00242 00243 PString errorString; 00244 PINDEX errorCol; 00245 PINDEX errorLine; 00246 00247 PSortedStringList noIndentElements; 00248 }; 00249 00251 00252 PARRAY(PXMLObjectArray, PXMLObject); 00253 00254 class PXMLObject : public PObject { 00255 PCLASSINFO(PXMLObject, PObject); 00256 public: 00257 PXMLObject(PXMLElement * _parent) 00258 : parent(_parent) { dirty = FALSE; } 00259 00260 PXMLElement * GetParent() 00261 { return parent; } 00262 00263 PXMLObject * GetNextObject(); 00264 00265 void SetParent(PXMLElement * newParent) 00266 { 00267 PAssert(parent == NULL, "Cannot reparent PXMLElement"); 00268 parent = newParent; 00269 } 00270 00271 virtual void Output(ostream & strm, const PXMLBase & xml, int indent) const = 0; 00272 00273 virtual BOOL IsElement() const = 0; 00274 00275 void SetDirty(); 00276 BOOL IsDirty() const { return dirty; } 00277 00278 virtual PXMLObject * Clone(PXMLElement * parent) const = 0; 00279 00280 protected: 00281 PXMLElement * parent; 00282 BOOL dirty; 00283 }; 00284 00286 00287 class PXMLData : public PXMLObject { 00288 PCLASSINFO(PXMLData, PXMLObject); 00289 public: 00290 PXMLData(PXMLElement * _parent, const PString & data); 00291 PXMLData(PXMLElement * _parent, const char * data, int len); 00292 00293 BOOL IsElement() const { return FALSE; } 00294 00295 void SetString(const PString & str, BOOL dirty = TRUE); 00296 00297 PString GetString() const { return value; } 00298 00299 void Output(ostream & strm, const PXMLBase & xml, int indent) const; 00300 00301 PXMLObject * Clone(PXMLElement * parent) const; 00302 00303 protected: 00304 PString value; 00305 }; 00306 00308 00309 class PXMLElement : public PXMLObject { 00310 PCLASSINFO(PXMLElement, PXMLObject); 00311 public: 00312 PXMLElement(PXMLElement * _parent, const char * name = NULL); 00313 PXMLElement(PXMLElement * _parent, const PString & name, const PString & data); 00314 00315 BOOL IsElement() const { return TRUE; } 00316 00317 void PrintOn(ostream & strm) const; 00318 void Output(ostream & strm, const PXMLBase & xml, int indent) const; 00319 00320 PCaselessString GetName() const 00321 { return name; } 00322 00323 void SetName(const PString & v) 00324 { name = v; } 00325 00326 PINDEX GetSize() const 00327 { return subObjects.GetSize(); } 00328 00329 PXMLObject * AddSubObject(PXMLObject * elem, BOOL dirty = TRUE); 00330 00331 PXMLElement * AddChild (PXMLElement * elem, BOOL dirty = TRUE); 00332 PXMLData * AddChild (PXMLData * elem, BOOL dirty = TRUE); 00333 00334 void SetAttribute(const PCaselessString & key, 00335 const PString & value, 00336 BOOL setDirty = TRUE); 00337 00338 PString GetAttribute(const PCaselessString & key) const; 00339 PString GetKeyAttribute(PINDEX idx) const; 00340 PString GetDataAttribute(PINDEX idx) const; 00341 BOOL HasAttribute(const PCaselessString & key); 00342 BOOL HasAttributes() const { return attributes.GetSize() > 0; } 00343 PINDEX GetNumAttributes() const { return attributes.GetSize(); } 00344 00345 PXMLElement * GetElement(const PCaselessString & name, PINDEX idx = 0) const; 00346 PXMLObject * GetElement(PINDEX idx = 0) const; 00347 BOOL RemoveElement(PINDEX idx); 00348 00349 PINDEX FindObject(PXMLObject * ptr) const; 00350 00351 BOOL HasSubObjects() const 00352 { return subObjects.GetSize() != 0; } 00353 00354 PXMLObjectArray GetSubObjects() const 00355 { return subObjects; } 00356 00357 PString GetData() const; 00358 00359 PXMLObject * Clone(PXMLElement * parent) const; 00360 00361 protected: 00362 PCaselessString name; 00363 PStringToString attributes; 00364 PXMLObjectArray subObjects; 00365 BOOL dirty; 00366 }; 00367 00369 00370 class PXMLSettings : public PXML 00371 { 00372 PCLASSINFO(PXMLSettings, PXML); 00373 public: 00374 PXMLSettings(int options = PXMLParser::NewLineAfterElement); 00375 PXMLSettings(const PString & data, int options = PXMLParser::NewLineAfterElement); 00376 PXMLSettings(const PConfig & data, int options = PXMLParser::NewLineAfterElement); 00377 00378 BOOL Load(const PString & data); 00379 BOOL LoadFile(const PFilePath & fn); 00380 00381 BOOL Save(); 00382 BOOL Save(PString & data); 00383 BOOL SaveFile(const PFilePath & fn); 00384 00385 void SetAttribute(const PCaselessString & section, const PString & key, const PString & value); 00386 00387 PString GetAttribute(const PCaselessString & section, const PString & key) const; 00388 BOOL HasAttribute(const PCaselessString & section, const PString & key) const; 00389 00390 void ToConfig(PConfig & cfg) const; 00391 }; 00392 00394 00395 class PXMLStreamParser : public PXMLParser 00396 { 00397 PCLASSINFO(PXMLStreamParser, PXMLParser); 00398 public: 00399 PXMLStreamParser(); 00400 00401 virtual void EndElement(const char * name); 00402 virtual PXML * Read(PChannel * channel); 00403 00404 protected: 00405 BOOL rootOpen; 00406 PQueue<PXML> messages; 00407 }; 00408 00409 #endif

Generated on Sat Jul 24 15:35:56 2004 for PWLib by doxygen 1.3.7