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