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

Generated on Thu May 27 01:36:48 2010 for PTLib by  doxygen 1.4.7