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

Generated on Mon Dec 10 11:18:57 2007 for PTLib by  doxygen 1.5.1