xml.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name: wx/xml/xml.h
  3. // Purpose: wxXmlDocument - XML parser & data holder class
  4. // Author: Vaclav Slavik
  5. // Created: 2000/03/05
  6. // Copyright: (c) 2000 Vaclav Slavik
  7. // Licence: wxWindows licence
  8. /////////////////////////////////////////////////////////////////////////////
  9. #ifndef _WX_XML_H_
  10. #define _WX_XML_H_
  11. #include "wx/defs.h"
  12. #if wxUSE_XML
  13. #include "wx/string.h"
  14. #include "wx/object.h"
  15. #include "wx/list.h"
  16. #include "wx/versioninfo.h"
  17. #ifdef WXMAKINGDLL_XML
  18. #define WXDLLIMPEXP_XML WXEXPORT
  19. #elif defined(WXUSINGDLL)
  20. #define WXDLLIMPEXP_XML WXIMPORT
  21. #else // not making nor using DLL
  22. #define WXDLLIMPEXP_XML
  23. #endif
  24. class WXDLLIMPEXP_FWD_XML wxXmlNode;
  25. class WXDLLIMPEXP_FWD_XML wxXmlAttribute;
  26. class WXDLLIMPEXP_FWD_XML wxXmlDocument;
  27. class WXDLLIMPEXP_FWD_XML wxXmlIOHandler;
  28. class WXDLLIMPEXP_FWD_BASE wxInputStream;
  29. class WXDLLIMPEXP_FWD_BASE wxOutputStream;
  30. // Represents XML node type.
  31. enum wxXmlNodeType
  32. {
  33. // note: values are synchronized with xmlElementType from libxml
  34. wxXML_ELEMENT_NODE = 1,
  35. wxXML_ATTRIBUTE_NODE = 2,
  36. wxXML_TEXT_NODE = 3,
  37. wxXML_CDATA_SECTION_NODE = 4,
  38. wxXML_ENTITY_REF_NODE = 5,
  39. wxXML_ENTITY_NODE = 6,
  40. wxXML_PI_NODE = 7,
  41. wxXML_COMMENT_NODE = 8,
  42. wxXML_DOCUMENT_NODE = 9,
  43. wxXML_DOCUMENT_TYPE_NODE = 10,
  44. wxXML_DOCUMENT_FRAG_NODE = 11,
  45. wxXML_NOTATION_NODE = 12,
  46. wxXML_HTML_DOCUMENT_NODE = 13
  47. };
  48. // Represents node property(ies).
  49. // Example: in <img src="hello.gif" id="3"/> "src" is property with value
  50. // "hello.gif" and "id" is prop. with value "3".
  51. class WXDLLIMPEXP_XML wxXmlAttribute
  52. {
  53. public:
  54. wxXmlAttribute() : m_next(NULL) {}
  55. wxXmlAttribute(const wxString& name, const wxString& value,
  56. wxXmlAttribute *next = NULL)
  57. : m_name(name), m_value(value), m_next(next) {}
  58. virtual ~wxXmlAttribute() {}
  59. const wxString& GetName() const { return m_name; }
  60. const wxString& GetValue() const { return m_value; }
  61. wxXmlAttribute *GetNext() const { return m_next; }
  62. void SetName(const wxString& name) { m_name = name; }
  63. void SetValue(const wxString& value) { m_value = value; }
  64. void SetNext(wxXmlAttribute *next) { m_next = next; }
  65. private:
  66. wxString m_name;
  67. wxString m_value;
  68. wxXmlAttribute *m_next;
  69. };
  70. #if WXWIN_COMPATIBILITY_2_8
  71. // NB: #define is used instead of typedef so that forward declarations
  72. // continue to work
  73. #define wxXmlProperty wxXmlAttribute
  74. #endif
  75. // Represents node in XML document. Node has name and may have content and
  76. // attributes. Most common node types are wxXML_TEXT_NODE (name and attributes
  77. // are irrelevant) and wxXML_ELEMENT_NODE (e.g. in <title>hi</title> there is
  78. // element with name="title", irrelevant content and one child (wxXML_TEXT_NODE
  79. // with content="hi").
  80. //
  81. // If wxUSE_UNICODE is 0, all strings are encoded in the encoding given to Load
  82. // (default is UTF-8).
  83. class WXDLLIMPEXP_XML wxXmlNode
  84. {
  85. public:
  86. wxXmlNode()
  87. : m_attrs(NULL), m_parent(NULL), m_children(NULL), m_next(NULL),
  88. m_lineNo(-1), m_noConversion(false)
  89. {
  90. }
  91. wxXmlNode(wxXmlNode *parent, wxXmlNodeType type,
  92. const wxString& name, const wxString& content = wxEmptyString,
  93. wxXmlAttribute *attrs = NULL, wxXmlNode *next = NULL,
  94. int lineNo = -1);
  95. virtual ~wxXmlNode();
  96. // copy ctor & operator=. Note that this does NOT copy siblings
  97. // and parent pointer, i.e. m_parent and m_next will be NULL
  98. // after using copy ctor and are never unmodified by operator=.
  99. // On the other hand, it DOES copy children and attributes.
  100. wxXmlNode(const wxXmlNode& node);
  101. wxXmlNode& operator=(const wxXmlNode& node);
  102. // user-friendly creation:
  103. wxXmlNode(wxXmlNodeType type, const wxString& name,
  104. const wxString& content = wxEmptyString,
  105. int lineNo = -1);
  106. virtual void AddChild(wxXmlNode *child);
  107. virtual bool InsertChild(wxXmlNode *child, wxXmlNode *followingNode);
  108. virtual bool InsertChildAfter(wxXmlNode *child, wxXmlNode *precedingNode);
  109. virtual bool RemoveChild(wxXmlNode *child);
  110. virtual void AddAttribute(const wxString& name, const wxString& value);
  111. virtual bool DeleteAttribute(const wxString& name);
  112. // access methods:
  113. wxXmlNodeType GetType() const { return m_type; }
  114. const wxString& GetName() const { return m_name; }
  115. const wxString& GetContent() const { return m_content; }
  116. bool IsWhitespaceOnly() const;
  117. int GetDepth(wxXmlNode *grandparent = NULL) const;
  118. // Gets node content from wxXML_ENTITY_NODE
  119. // The problem is, <tag>content<tag> is represented as
  120. // wxXML_ENTITY_NODE name="tag", content=""
  121. // |-- wxXML_TEXT_NODE or
  122. // wxXML_CDATA_SECTION_NODE name="" content="content"
  123. wxString GetNodeContent() const;
  124. wxXmlNode *GetParent() const { return m_parent; }
  125. wxXmlNode *GetNext() const { return m_next; }
  126. wxXmlNode *GetChildren() const { return m_children; }
  127. wxXmlAttribute *GetAttributes() const { return m_attrs; }
  128. bool GetAttribute(const wxString& attrName, wxString *value) const;
  129. wxString GetAttribute(const wxString& attrName,
  130. const wxString& defaultVal = wxEmptyString) const;
  131. bool HasAttribute(const wxString& attrName) const;
  132. int GetLineNumber() const { return m_lineNo; }
  133. void SetType(wxXmlNodeType type) { m_type = type; }
  134. void SetName(const wxString& name) { m_name = name; }
  135. void SetContent(const wxString& con) { m_content = con; }
  136. void SetParent(wxXmlNode *parent) { m_parent = parent; }
  137. void SetNext(wxXmlNode *next) { m_next = next; }
  138. void SetChildren(wxXmlNode *child) { m_children = child; }
  139. void SetAttributes(wxXmlAttribute *attr) { m_attrs = attr; }
  140. virtual void AddAttribute(wxXmlAttribute *attr);
  141. // If true, don't do encoding conversion to improve efficiency - node content is ACII text
  142. bool GetNoConversion() const { return m_noConversion; }
  143. void SetNoConversion(bool noconversion) { m_noConversion = noconversion; }
  144. #if WXWIN_COMPATIBILITY_2_8
  145. wxDEPRECATED( inline wxXmlAttribute *GetProperties() const );
  146. wxDEPRECATED( inline bool GetPropVal(const wxString& propName,
  147. wxString *value) const );
  148. wxDEPRECATED( inline wxString GetPropVal(const wxString& propName,
  149. const wxString& defaultVal) const );
  150. wxDEPRECATED( inline bool HasProp(const wxString& propName) const );
  151. wxDEPRECATED( inline void SetProperties(wxXmlAttribute *prop) );
  152. #endif // WXWIN_COMPATIBILITY_2_8
  153. // The following three functions are backward compatibility, but because
  154. // they were virtual, we must make it possible to override them. This
  155. // is done by calling e.g. AddProperty() from AddAttribute(), so we have
  156. // to keep AddProperty() even if 2.8 compatibility is off. To prevent
  157. // old code from compiling in that case, we make them private and
  158. // non-virtual. (This can be removed when WXWIN_COMPATIBILITY_2_8 is
  159. // removed, we'll have just *Attribute versions then.)
  160. #if WXWIN_COMPATIBILITY_2_8
  161. wxDEPRECATED_BUT_USED_INTERNALLY(
  162. virtual void AddProperty(const wxString& name, const wxString& value) );
  163. wxDEPRECATED_BUT_USED_INTERNALLY(
  164. virtual bool DeleteProperty(const wxString& name) );
  165. wxDEPRECATED_BUT_USED_INTERNALLY(
  166. virtual void AddProperty(wxXmlAttribute *attr) );
  167. #else
  168. private:
  169. void AddProperty(const wxString& name, const wxString& value);
  170. bool DeleteProperty(const wxString& name);
  171. void AddProperty(wxXmlAttribute *attr);
  172. #endif // WXWIN_COMPATIBILITY_2_8/!WXWIN_COMPATIBILITY_2_8
  173. private:
  174. wxXmlNodeType m_type;
  175. wxString m_name;
  176. wxString m_content;
  177. wxXmlAttribute *m_attrs;
  178. wxXmlNode *m_parent, *m_children, *m_next;
  179. int m_lineNo; // line number in original file, or -1
  180. bool m_noConversion; // don't do encoding conversion - node is plain text
  181. void DoFree();
  182. void DoCopy(const wxXmlNode& node);
  183. };
  184. #if WXWIN_COMPATIBILITY_2_8
  185. inline wxXmlAttribute *wxXmlNode::GetProperties() const
  186. { return GetAttributes(); }
  187. inline bool wxXmlNode::GetPropVal(const wxString& propName,
  188. wxString *value) const
  189. { return GetAttribute(propName, value); }
  190. inline wxString wxXmlNode::GetPropVal(const wxString& propName,
  191. const wxString& defaultVal) const
  192. { return GetAttribute(propName, defaultVal); }
  193. inline bool wxXmlNode::HasProp(const wxString& propName) const
  194. { return HasAttribute(propName); }
  195. inline void wxXmlNode::SetProperties(wxXmlAttribute *prop)
  196. { SetAttributes(prop); }
  197. #endif // WXWIN_COMPATIBILITY_2_8
  198. // special indentation value for wxXmlDocument::Save
  199. #define wxXML_NO_INDENTATION (-1)
  200. // flags for wxXmlDocument::Load
  201. enum wxXmlDocumentLoadFlag
  202. {
  203. wxXMLDOC_NONE = 0,
  204. wxXMLDOC_KEEP_WHITESPACE_NODES = 1
  205. };
  206. // This class holds XML data/document as parsed by XML parser.
  207. class WXDLLIMPEXP_XML wxXmlDocument : public wxObject
  208. {
  209. public:
  210. wxXmlDocument();
  211. wxXmlDocument(const wxString& filename,
  212. const wxString& encoding = wxT("UTF-8"));
  213. wxXmlDocument(wxInputStream& stream,
  214. const wxString& encoding = wxT("UTF-8"));
  215. virtual ~wxXmlDocument() { wxDELETE(m_docNode); }
  216. wxXmlDocument(const wxXmlDocument& doc);
  217. wxXmlDocument& operator=(const wxXmlDocument& doc);
  218. // Parses .xml file and loads data. Returns TRUE on success, FALSE
  219. // otherwise.
  220. virtual bool Load(const wxString& filename,
  221. const wxString& encoding = wxT("UTF-8"), int flags = wxXMLDOC_NONE);
  222. virtual bool Load(wxInputStream& stream,
  223. const wxString& encoding = wxT("UTF-8"), int flags = wxXMLDOC_NONE);
  224. // Saves document as .xml file.
  225. virtual bool Save(const wxString& filename, int indentstep = 2) const;
  226. virtual bool Save(wxOutputStream& stream, int indentstep = 2) const;
  227. bool IsOk() const { return GetRoot() != NULL; }
  228. // Returns root node of the document.
  229. wxXmlNode *GetRoot() const;
  230. // Returns the document node.
  231. wxXmlNode *GetDocumentNode() const { return m_docNode; }
  232. // Returns version of document (may be empty).
  233. const wxString& GetVersion() const { return m_version; }
  234. // Returns encoding of document (may be empty).
  235. // Note: this is the encoding original file was saved in, *not* the
  236. // encoding of in-memory representation!
  237. const wxString& GetFileEncoding() const { return m_fileEncoding; }
  238. // Write-access methods:
  239. wxXmlNode *DetachDocumentNode() { wxXmlNode *old=m_docNode; m_docNode=NULL; return old; }
  240. void SetDocumentNode(wxXmlNode *node) { wxDELETE(m_docNode); m_docNode = node; }
  241. wxXmlNode *DetachRoot();
  242. void SetRoot(wxXmlNode *node);
  243. void SetVersion(const wxString& version) { m_version = version; }
  244. void SetFileEncoding(const wxString& encoding) { m_fileEncoding = encoding; }
  245. void AppendToProlog(wxXmlNode *node);
  246. #if !wxUSE_UNICODE
  247. // Returns encoding of in-memory representation of the document
  248. // (same as passed to Load or ctor, defaults to UTF-8).
  249. // NB: this is meaningless in Unicode build where data are stored as wchar_t*
  250. wxString GetEncoding() const { return m_encoding; }
  251. void SetEncoding(const wxString& enc) { m_encoding = enc; }
  252. #endif
  253. static wxVersionInfo GetLibraryVersionInfo();
  254. private:
  255. wxString m_version;
  256. wxString m_fileEncoding;
  257. #if !wxUSE_UNICODE
  258. wxString m_encoding;
  259. #endif
  260. wxXmlNode *m_docNode;
  261. void DoCopy(const wxXmlDocument& doc);
  262. DECLARE_CLASS(wxXmlDocument)
  263. };
  264. #endif // wxUSE_XML
  265. #endif // _WX_XML_H_