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
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 #ifndef _PXML_H
00066 #define _PXML_H
00067
00068 #ifdef P_USE_PRAGMA
00069 #pragma interface
00070 #endif
00071
00072 #include <ptlib.h>
00073 #include <ptclib/http.h>
00074
00076
00077 class PXMLElement;
00078 class PXMLData;
00079
00080 class PXMLParser : public PObject
00081 {
00082 PCLASSINFO(PXMLParser, PObject);
00083 public:
00084 enum Options {
00085 Indent = 1,
00086 NewLineAfterElement = 2,
00087 NoIgnoreWhiteSpace = 4,
00088 CloseExtended = 8,
00089 WithNS = 16,
00090 };
00091
00092 PXMLParser(int options = -1);
00093 ~PXMLParser();
00094 BOOL Parse(const char * data, int dataLen, BOOL final);
00095 void GetErrorInfo(PString & errorString, PINDEX & errorCol, PINDEX & errorLine);
00096
00097 virtual void StartElement(const char * name, const char **attrs);
00098 virtual void EndElement(const char * name);
00099 virtual void AddCharacterData(const char * data, int len);
00100 virtual void XmlDecl(const char * version, const char * encoding, int standAlone);
00101 virtual void StartDocTypeDecl(const char * docTypeName,
00102 const char * sysid,
00103 const char * pubid,
00104 int hasInternalSubSet);
00105 virtual void EndDocTypeDecl();
00106 virtual void StartNamespaceDeclHandler(const char * prefix, const char * uri);
00107 virtual void EndNamespaceDeclHandler(const char * prefix);
00108
00109 PString GetVersion() const { return version; }
00110 PString GetEncoding() const { return encoding; }
00111 BOOL GetStandAlone() const { return standAlone; }
00112
00113 PXMLElement * GetXMLTree() const;
00114 PXMLElement * SetXMLTree(PXMLElement * newRoot);
00115
00116 protected:
00117 int options;
00118 void * expat;
00119 PXMLElement * rootElement;
00120 PXMLElement * currentElement;
00121 PXMLData * lastElement;
00122 PString version, encoding;
00123 int standAlone;
00124 };
00125
00126 class PXMLObject;
00127 class PXMLElement;
00128 class PXMLData;
00129
00131
00132 class PXMLBase : public PObject
00133 {
00134 public:
00135 PXMLBase(int _options = -1)
00136 : options(_options) { if (options < 0) options = 0; }
00137
00138 void SetOptions(int _options)
00139 { options = _options; }
00140
00141 int GetOptions() const { return options; }
00142
00143 virtual BOOL IsNoIndentElement(
00144 const PString &
00145 ) const
00146 {
00147 return FALSE;
00148 }
00149
00150 protected:
00151 int options;
00152 };
00153
00154
00155 class PXML : public PXMLBase
00156 {
00157 PCLASSINFO(PXML, PObject);
00158 public:
00159
00160 PXML(
00161 int options = -1,
00162 const char * noIndentElements = NULL
00163 );
00164 PXML(
00165 const PString & data,
00166 int options = -1,
00167 const char * noIndentElements = NULL
00168 );
00169
00170 PXML(const PXML & xml);
00171
00172 ~PXML();
00173
00174 BOOL IsDirty() const;
00175
00176 BOOL Load(const PString & data, int options = -1);
00177
00178 BOOL StartAutoReloadURL(const PURL & url,
00179 const PTimeInterval & timeout,
00180 const PTimeInterval & refreshTime,
00181 int _options = -1);
00182 BOOL StopAutoReloadURL();
00183 PString GetAutoReloadStatus() { PWaitAndSignal m(autoLoadMutex); PString str = autoLoadError; return str; }
00184 BOOL AutoLoadURL();
00185 virtual void OnAutoLoad(BOOL ok);
00186
00187 BOOL LoadURL(const PURL & url);
00188 BOOL LoadURL(const PURL & url, const PTimeInterval & timeout, int _options = -1);
00189 BOOL LoadFile(const PFilePath & fn, int options = -1);
00190
00191 virtual void OnLoaded() { }
00192
00193 BOOL Save(int options = -1);
00194 BOOL Save(PString & data, int options = -1);
00195 BOOL SaveFile(const PFilePath & fn, int options = -1);
00196
00197 void RemoveAll();
00198
00199 BOOL IsNoIndentElement(
00200 const PString & elementName
00201 ) const;
00202
00203 void PrintOn(ostream & strm) const;
00204
00205 PXMLElement * GetElement(const PCaselessString & name, PINDEX idx = 0) const;
00206 PXMLElement * GetElement(PINDEX idx) const;
00207 PINDEX GetNumElements() const;
00208 PXMLElement * GetRootElement() const { return rootElement; }
00209 PXMLElement * SetRootElement(PXMLElement * p);
00210 PXMLElement * SetRootElement(const PString & documentType);
00211 BOOL RemoveElement(PINDEX idx);
00212
00213 PCaselessString GetDocumentType() const;
00214
00215 PString GetErrorString() const { return errorString; }
00216 PINDEX GetErrorColumn() const { return errorCol; }
00217 PINDEX GetErrorLine() const { return errorLine; }
00218
00219 PString GetDocType() const { return docType; }
00220 void SetDocType(const PString & v) { docType = v; }
00221
00222 PMutex & GetMutex() { return rootMutex; }
00223
00224 PDECLARE_NOTIFIER(PTimer, PXML, AutoReloadTimeout);
00225 PDECLARE_NOTIFIER(PThread, PXML, AutoReloadThread);
00226
00227
00228 static PString CreateStartTag (const PString & text);
00229 static PString CreateEndTag (const PString & text);
00230 static PString CreateTagNoData (const PString & text);
00231 static PString CreateTag (const PString & text, const PString & data);
00232
00233 protected:
00234 void Construct(int options, const char * noIndentElements);
00235 PXMLElement * rootElement;
00236 PMutex rootMutex;
00237
00238 BOOL loadFromFile;
00239 PFilePath loadFilename;
00240 PString version, encoding;
00241 int standAlone;
00242
00243 PTimer autoLoadTimer;
00244 PURL autoloadURL;
00245 PTimeInterval autoLoadWaitTime;
00246 PMutex autoLoadMutex;
00247 PString autoLoadError;
00248
00249 PString errorString;
00250 PINDEX errorCol;
00251 PINDEX errorLine;
00252
00253 PSortedStringList noIndentElements;
00254
00255 PString docType;
00256 };
00257
00259
00260 PARRAY(PXMLObjectArray, PXMLObject);
00261
00262 class PXMLObject : public PObject {
00263 PCLASSINFO(PXMLObject, PObject);
00264 public:
00265 PXMLObject(PXMLElement * _parent)
00266 : parent(_parent) { dirty = FALSE; }
00267
00268 PXMLElement * GetParent()
00269 { return parent; }
00270
00271 PXMLObject * GetNextObject();
00272
00273 void SetParent(PXMLElement * newParent)
00274 {
00275 PAssert(parent == NULL, "Cannot reparent PXMLElement");
00276 parent = newParent;
00277 }
00278
00279 virtual void Output(ostream & strm, const PXMLBase & xml, int indent) const = 0;
00280
00281 virtual BOOL IsElement() const = 0;
00282
00283 void SetDirty();
00284 BOOL IsDirty() const { return dirty; }
00285
00286 virtual PXMLObject * Clone(PXMLElement * parent) const = 0;
00287
00288 protected:
00289 PXMLElement * parent;
00290 BOOL dirty;
00291 };
00292
00294
00295 class PXMLData : public PXMLObject {
00296 PCLASSINFO(PXMLData, PXMLObject);
00297 public:
00298 PXMLData(PXMLElement * _parent, const PString & data);
00299 PXMLData(PXMLElement * _parent, const char * data, int len);
00300
00301 BOOL IsElement() const { return FALSE; }
00302
00303 void SetString(const PString & str, BOOL dirty = TRUE);
00304
00305 PString GetString() const { return value; }
00306
00307 void Output(ostream & strm, const PXMLBase & xml, int indent) const;
00308
00309 PXMLObject * Clone(PXMLElement * parent) const;
00310
00311 protected:
00312 PString value;
00313 };
00314
00316
00317 class PXMLElement : public PXMLObject {
00318 PCLASSINFO(PXMLElement, PXMLObject);
00319 public:
00320 PXMLElement(PXMLElement * _parent, const char * name = NULL);
00321 PXMLElement(PXMLElement * _parent, const PString & name, const PString & data);
00322
00323 BOOL IsElement() const { return TRUE; }
00324
00325 void PrintOn(ostream & strm) const;
00326 void Output(ostream & strm, const PXMLBase & xml, int indent) const;
00327
00328 PCaselessString GetName() const
00329 { return name; }
00330
00331 void SetName(const PString & v)
00332 { name = v; }
00333
00334 PINDEX GetSize() const
00335 { return subObjects.GetSize(); }
00336
00337 PXMLObject * AddSubObject(PXMLObject * elem, BOOL dirty = TRUE);
00338
00339 PXMLElement * AddChild (PXMLElement * elem, BOOL dirty = TRUE);
00340 PXMLData * AddChild (PXMLData * elem, BOOL dirty = TRUE);
00341
00342 void SetAttribute(const PCaselessString & key,
00343 const PString & value,
00344 BOOL setDirty = TRUE);
00345
00346 PString GetAttribute(const PCaselessString & key) const;
00347 PString GetKeyAttribute(PINDEX idx) const;
00348 PString GetDataAttribute(PINDEX idx) const;
00349 BOOL HasAttribute(const PCaselessString & key);
00350 BOOL HasAttributes() const { return attributes.GetSize() > 0; }
00351 PINDEX GetNumAttributes() const { return attributes.GetSize(); }
00352
00353 PXMLElement * GetElement(const PCaselessString & name, PINDEX idx = 0) const;
00354 PXMLObject * GetElement(PINDEX idx = 0) const;
00355 BOOL RemoveElement(PINDEX idx);
00356
00357 PINDEX FindObject(PXMLObject * ptr) const;
00358
00359 BOOL HasSubObjects() const
00360 { return subObjects.GetSize() != 0; }
00361
00362 PXMLObjectArray GetSubObjects() const
00363 { return subObjects; }
00364
00365 PString GetData() const;
00366
00367 PXMLObject * Clone(PXMLElement * parent) const;
00368
00369 protected:
00370 PCaselessString name;
00371 PStringToString attributes;
00372 PXMLObjectArray subObjects;
00373 BOOL dirty;
00374 };
00375
00377
00378 class PXMLSettings : public PXML
00379 {
00380 PCLASSINFO(PXMLSettings, PXML);
00381 public:
00382 PXMLSettings(int options = PXMLParser::NewLineAfterElement);
00383 PXMLSettings(const PString & data, int options = PXMLParser::NewLineAfterElement);
00384 PXMLSettings(const PConfig & data, int options = PXMLParser::NewLineAfterElement);
00385
00386 BOOL Load(const PString & data);
00387 BOOL LoadFile(const PFilePath & fn);
00388
00389 BOOL Save();
00390 BOOL Save(PString & data);
00391 BOOL SaveFile(const PFilePath & fn);
00392
00393 void SetAttribute(const PCaselessString & section, const PString & key, const PString & value);
00394
00395 PString GetAttribute(const PCaselessString & section, const PString & key) const;
00396 BOOL HasAttribute(const PCaselessString & section, const PString & key) const;
00397
00398 void ToConfig(PConfig & cfg) const;
00399 };
00400
00402
00403 class PXMLStreamParser : public PXMLParser
00404 {
00405 PCLASSINFO(PXMLStreamParser, PXMLParser);
00406 public:
00407 PXMLStreamParser();
00408
00409 virtual void EndElement(const char * name);
00410 virtual PXML * Read(PChannel * channel);
00411
00412 protected:
00413 BOOL rootOpen;
00414 PQueue<PXML> messages;
00415 };
00416
00417 #endif