Line data Source code
1 : /**********************************************************************
2 : *
3 : * Project: CPL - Common Portability Library
4 : * Purpose: Declarations for MiniXML Handler.
5 : * Author: Frank Warmerdam, warmerdam@pobox.com
6 : *
7 : **********************************************************************
8 : * Copyright (c) 2001, Frank Warmerdam
9 : *
10 : * SPDX-License-Identifier: MIT
11 : ****************************************************************************/
12 :
13 : #ifndef CPL_MINIXML_H_INCLUDED
14 : #define CPL_MINIXML_H_INCLUDED
15 :
16 : #include "cpl_port.h"
17 :
18 : /**
19 : * \file cpl_minixml.h
20 : *
21 : * Definitions for CPL mini XML Parser/Serializer.
22 : */
23 :
24 : CPL_C_START
25 :
26 : /** XML node type */
27 : typedef enum
28 : {
29 : /*! Node is an element */ CXT_Element = 0,
30 : /*! Node is a raw text value */ CXT_Text = 1,
31 : /*! Node is attribute */ CXT_Attribute = 2,
32 : /*! Node is an XML comment. */ CXT_Comment = 3,
33 : /*! Node is a special literal */ CXT_Literal = 4
34 : } CPLXMLNodeType;
35 :
36 : /*! @cond Doxygen_Suppress */
37 : typedef struct CPLXMLNode CPLXMLNode;
38 :
39 : /*! @endcond */
40 :
41 : /**
42 : * Document node structure.
43 : *
44 : * This C structure is used to hold a single text fragment representing a
45 : * component of the document when parsed. It should be allocated with the
46 : * appropriate CPL function, and freed with CPLDestroyXMLNode(). The structure
47 : * contents should not normally be altered by application code, but may be
48 : * freely examined by application code.
49 : *
50 : * Using the psChild and psNext pointers, a hierarchical tree structure
51 : * for a document can be represented as a tree of CPLXMLNode structures.
52 : */
53 : struct CPLXMLNode
54 : {
55 : /**
56 : * \brief Node type
57 : *
58 : * One of CXT_Element, CXT_Text, CXT_Attribute, CXT_Comment,
59 : * or CXT_Literal.
60 : */
61 : CPLXMLNodeType eType;
62 :
63 : /**
64 : * \brief Node value
65 : *
66 : * For CXT_Element this is the name of the element, without the angle
67 : * brackets. Note there is a single CXT_Element even when the document
68 : * contains a start and end element tag. The node represents the pair.
69 : * All text or other elements between the start and end tag will appear
70 : * as children nodes of this CXT_Element node.
71 : *
72 : * For CXT_Attribute the pszValue is the attribute name. The value of
73 : * the attribute will be a CXT_Text child.
74 : *
75 : * For CXT_Text this is the text itself (value of an attribute, or a
76 : * text fragment between an element start and end tags.
77 : *
78 : * For CXT_Literal it is all the literal text. Currently this is just
79 : * used for !DOCTYPE lines, and the value would be the entire line.
80 : *
81 : * For CXT_Comment the value is all the literal text within the comment,
82 : * but not including the comment start/end indicators ("<--" and "-->").
83 : */
84 : char *pszValue;
85 :
86 : /**
87 : * \brief Next sibling.
88 : *
89 : * Pointer to next sibling, that is the next node appearing after this
90 : * one that has the same parent as this node. NULL if this node is the
91 : * last child of the parent element.
92 : */
93 : struct CPLXMLNode *psNext;
94 :
95 : /**
96 : * \brief Child node.
97 : *
98 : * Pointer to first child node, if any. Only CXT_Element and CXT_Attribute
99 : * nodes should have children. For CXT_Attribute it should be a single
100 : * CXT_Text value node, while CXT_Element can have any kind of child.
101 : * The full list of children for a node are identified by walking the
102 : * psNext's starting with the psChild node.
103 : */
104 :
105 : struct CPLXMLNode *psChild;
106 : };
107 :
108 : CPLXMLNode CPL_DLL *CPLParseXMLString(const char *);
109 : void CPL_DLL CPLDestroyXMLNode(CPLXMLNode *);
110 : CPLXMLNode CPL_DLL *CPLGetXMLNode(CPLXMLNode *poRoot, const char *pszPath);
111 : #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
112 : /*! @cond Doxygen_Suppress */
113 : extern "C++"
114 : {
115 1701662 : inline const CPLXMLNode *CPLGetXMLNode(const CPLXMLNode *poRoot,
116 : const char *pszPath)
117 : {
118 : return const_cast<const CPLXMLNode *>(
119 1701662 : CPLGetXMLNode(const_cast<CPLXMLNode *>(poRoot), pszPath));
120 : }
121 : }
122 : /*! @endcond */
123 : #endif
124 : CPLXMLNode CPL_DLL *CPLSearchXMLNode(CPLXMLNode *poRoot, const char *pszTarget);
125 : #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
126 : /*! @cond Doxygen_Suppress */
127 : extern "C++"
128 : {
129 : inline const CPLXMLNode *CPLSearchXMLNode(const CPLXMLNode *poRoot,
130 : const char *pszTarget)
131 : {
132 : return const_cast<const CPLXMLNode *>(
133 : CPLSearchXMLNode(const_cast<CPLXMLNode *>(poRoot), pszTarget));
134 : }
135 : }
136 : /*! @endcond */
137 : #endif
138 : const char CPL_DLL *CPLGetXMLValue(const CPLXMLNode *poRoot,
139 : const char *pszPath, const char *pszDefault);
140 : CPLXMLNode CPL_DLL *CPLCreateXMLNode(CPLXMLNode *poParent, CPLXMLNodeType eType,
141 : const char *pszText);
142 : char CPL_DLL *CPLSerializeXMLTree(const CPLXMLNode *psNode);
143 : void CPL_DLL CPLAddXMLChild(CPLXMLNode *psParent, CPLXMLNode *psChild);
144 : int CPL_DLL CPLRemoveXMLChild(CPLXMLNode *psParent, CPLXMLNode *psChild);
145 : void CPL_DLL CPLAddXMLSibling(CPLXMLNode *psOlderSibling,
146 : CPLXMLNode *psNewSibling);
147 : CPLXMLNode CPL_DLL *CPLCreateXMLElementAndValue(CPLXMLNode *psParent,
148 : const char *pszName,
149 : const char *pszValue);
150 : void CPL_DLL CPLAddXMLAttributeAndValue(CPLXMLNode *psParent,
151 : const char *pszName,
152 : const char *pszValue);
153 : CPLXMLNode CPL_DLL *CPLCloneXMLTree(const CPLXMLNode *psTree);
154 : int CPL_DLL CPLSetXMLValue(CPLXMLNode *psRoot, const char *pszPath,
155 : const char *pszValue);
156 : void CPL_DLL CPLStripXMLNamespace(CPLXMLNode *psRoot, const char *pszNameSpace,
157 : int bRecurse);
158 : void CPL_DLL CPLCleanXMLElementName(char *);
159 :
160 : CPLXMLNode CPL_DLL *CPLParseXMLFile(const char *pszFilename);
161 : int CPL_DLL CPLSerializeXMLTreeToFile(const CPLXMLNode *psTree,
162 : const char *pszFilename);
163 :
164 : size_t CPL_DLL CPLXMLNodeGetRAMUsageEstimate(const CPLXMLNode *psNode);
165 :
166 : CPL_C_END
167 :
168 : #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
169 :
170 : extern "C++"
171 : {
172 : #ifndef DOXYGEN_SKIP
173 : #include <memory>
174 : #endif
175 :
176 : /*! @cond Doxygen_Suppress */
177 : struct CPL_DLL CPLXMLTreeCloserDeleter
178 : {
179 12926 : void operator()(CPLXMLNode *psNode) const
180 : {
181 12926 : CPLDestroyXMLNode(psNode);
182 12926 : }
183 : };
184 :
185 : /*! @endcond */
186 :
187 : /** Manage a tree of XML nodes so that all nodes are freed when the instance
188 : * goes out of scope. Only the top level node should be in a
189 : * CPLXMLTreeCloser.
190 : */
191 : class CPL_DLL CPLXMLTreeCloser
192 : : public std::unique_ptr<CPLXMLNode, CPLXMLTreeCloserDeleter>
193 : {
194 : public:
195 : /** Constructor */
196 15375 : explicit CPLXMLTreeCloser(CPLXMLNode *data)
197 15375 : : std::unique_ptr<CPLXMLNode, CPLXMLTreeCloserDeleter>(data)
198 : {
199 15375 : }
200 :
201 : /** Returns a pointer to the document (root) element
202 : * @return the node pointer */
203 : CPLXMLNode *getDocumentElement();
204 : };
205 :
206 : } // extern "C++"
207 :
208 : #endif /* __cplusplus */
209 :
210 : #endif /* CPL_MINIXML_H_INCLUDED */
|