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