acl  3.5.3.0
acl_xml3.h
浏览该文件的文档.
1 #ifndef ACL_XML3_INCLUDE_H
2 #define ACL_XML3_INCLUDE_H
3 
4 #ifdef __cplusplus
5 extern "C" {
6 #endif
7 
8 #include "../stdlib/acl_array.h"
9 #include "../stdlib/acl_ring.h"
10 #include "../stdlib/acl_vstream.h"
11 #include "../stdlib/acl_htable.h"
12 #include "../stdlib/acl_vstring.h"
13 #include "../stdlib/acl_iterator.h"
14 #include "../stdlib/acl_dbuf_pool.h"
15 
16 typedef struct ACL_XML3 ACL_XML3;
19 
20 struct ACL_XML3_ATTR {
21  ACL_XML3_NODE *node; /**< 所属节点 */
22  char *name; /**< 属性名 */
23  char *value; /**< 属性值 */
24 
25  size_t name_size; /**< 属性名长度 */
26  size_t value_size; /**< 属性值长度 */
27 
28  /* private */
29  int quote; /**< 非 0 表示 ' 或 " */
30  int backslash; /**< 转义字符 \ */
31  int slash; /**< 是否有 '/' 标志位设定 */
32 };
33 
34 struct ACL_XML3_NODE {
35  char *ltag; /**< 左标签名 */
36  char *rtag; /**< 右标签名 */
37  size_t ltag_size; /**< 左标签名长度 */
38  size_t rtag_size; /**< 右标签名长度 */
39  const char *id; /**< ID标识符, 只有在 xml->id_table
40  存在的节点的 id 才非空 */
41  char *text; /**< 文本显示内容 */
42  size_t text_size; /**< 文件数据长度 */
43 
44  ACL_ARRAY *attr_list; /**< 属性(ACL_XML3_ATTR)列表 */
45  ACL_XML3_NODE *parent; /**< 父节点 */
46  ACL_RING children; /**< 子节点集合 */
47  int depth; /**< 当前节点的深度 */
48 
49  /* private */
50  ACL_XML3 *xml; /**< xml 对象 */
51  ACL_RING node; /**< 当前节点 */
52  ACL_XML3_ATTR *curr_attr; /**< 当前正在解析的属性 */
53  int quote; /**< 非 0 表示 ' 或 " */
54  int last_ch; /**< 所记录本节点的前一个字节值 */
55  int nlt; /**< '<' 个数 */
56  char meta[3]; /**< 元数据临时缓冲区 */
57 
58  unsigned int flag;
59 #define ACL_XML3_F_META_QM (1 << 0) /**< '?' flag */
60 #define ACL_XML3_F_META_CM (1 << 1) /**< '!--' flag */
61 #define ACL_XML3_F_META_EM (1 << 2) /**< only '!' flag */
62 #define ACL_XML3_F_SELF_CL (1 << 3) /**< self closed flag */
63 #define ACL_XML3_F_LEAF (1 << 4) /**< leaf node has no child node */
64 
65 /**< 是否是元数据 */
66 #define ACL_XML3_F_META \
67  (ACL_XML3_F_META_QM | ACL_XML3_F_META_CM | ACL_XML3_F_META_EM)
68 
69 #define ACL_XML3_IS_COMMENT(x) (((x)->flag & ACL_XML3_F_META_CM))
70 
71  int status; /**< 状态机当前解析状态 */
72 #define ACL_XML3_S_NXT 0 /**< 下一个节点 */
73 #define ACL_XML3_S_LLT 1 /**< 左边 '<' */
74 #define ACL_XML3_S_LGT 2 /**< 右边 '>' */
75 #define ACL_XML3_S_LCH 3 /**< 左边 '<' 后第一个字节 */
76 #define ACL_XML3_S_LEM 4 /**< 左边 '<' 后的 '!' */
77 #define ACL_XML3_S_LTAG 5 /**< 左边的标签名 */
78 #define ACL_XML3_S_RLT 6 /**< 右边的 '<' */
79 #define ACL_XML3_S_RGT 7 /**< 右边的 '>' */
80 #define ACL_XML3_S_RTAG 8 /**< 右边的标签名 */
81 #define ACL_XML3_S_ATTR 9 /**< 标签属性名 */
82 #define ACL_XML3_S_AVAL 10 /**< 标签属性值 */
83 #define ACL_XML3_S_TXT 11 /**< 节点文本 */
84 #define ACL_XML3_S_MTAG 12 /**< 元数据标签 */
85 #define ACL_XML3_S_MTXT 13 /**< 元数据文本 */
86 #define ACL_XML3_S_MCMT 14 /**< 元数据注释 */
87 #define ACL_XML3_S_MEND 15 /**< 元数据结束 */
88 
89  /* for acl_iterator, 通过 acl_foreach 列出该节点的一级子节点 */
90 
91  /* 取迭代器头函数 */
93  /* 取迭代器下一个函数 */
95  /* 取迭代器尾函数 */
97  /* 取迭代器上一个函数 */
99 };
100 
101 struct ACL_XML3 {
102  /* public */
103 
104  int depth; /**< 最大深度 */
105  int node_cnt; /**< 节点总数, 包括 root 节点 */
106  int root_cnt; /**< 根节点个数 */
107  ACL_XML3_NODE *root; /**< XML 根节点 */
108 
109  /* private */
110  char addr[1];
111  ACL_HTABLE *id_table; /**< id 标识符哈希表 */
112  ACL_XML3_NODE *curr_node; /**< 当前正在处理的 XML 节点 */
113  ACL_DBUF_POOL *dbuf; /**< 内存池对象 */
114  ACL_DBUF_POOL *dbuf_inner; /**< 内部分布的内存池对象 */
115  size_t dbuf_keep; /**< 内存池中保留的长度 */
116 
117  unsigned flag; /**< 标志位: ACL_XML3_FLAG_xxx */
118 
119  /**< 是否允许一个 xml 文档中有多个根节点,内部缺省为允许 */
120 #define ACL_XML3_FLAG_MULTI_ROOT (1 << 0)
121 
122  /**< 是否兼容单节点中没有 '/' 情况 */
123 #define ACL_XML3_FLAG_IGNORE_SLASH (1 << 1)
124 
125  /* for acl_iterator, 通过 acl_foreach 可以列出所有子节点 */
126 
127  /* 取迭代器头函数 */
128  ACL_XML3_NODE *(*iter_head)(ACL_ITER*, ACL_XML3*);
129  /* 取迭代器下一个函数 */
130  ACL_XML3_NODE *(*iter_next)(ACL_ITER*, ACL_XML3*);
131  /* 取迭代器尾函数 */
132  ACL_XML3_NODE *(*iter_tail)(ACL_ITER*, ACL_XML3*);
133  /* 取迭代器上一个函数 */
134  ACL_XML3_NODE *(*iter_prev)(ACL_ITER*, ACL_XML3*);
135 };
136 
137 /****************************************************************************/
138 /* 公共函数接口,用户可以放心使用该接口集 */
139 /****************************************************************************/
140 
141 /*----------------------------- in acl_xml3.c ------------------------------*/
142 
143 /**
144  * 判断 xml 对象是否闭合的, 即是否所解析的数据是否完整, 如果该 xml 对象里的
145  * xml 节点元素为空, 则也认为不是闭合的
146  * @param xml {ACL_XML3*} xml 对象
147  * @return {int} 0: 否; 1: 是
148  */
149 ACL_API int acl_xml3_is_closure(ACL_XML3 *xml);
150 
151 /**
152  * 根据指定标签名判断 xml 解析已经完成, 当该标签与 xml 对象中 root 一级子节点
153  * 中的最后一个 xml 节点的标签相同时, 则认为 xml 解析完成, 为保证判断的正确性,
154  * 数据源应保证最外层的根节点只有一个, 即 xml->root 的一级子节点只有一个, 否则
155  * 会造成误判
156  * @param xml {ACL_XML3*} xml 对象
157  * @param tag {const char*} 用户给定标签名, 内部在匹配时不区分大小写
158  * @return {int} 0: 否; 1: 是
159  */
160 ACL_API int acl_xml3_is_complete(ACL_XML3 *xml, const char *tag);
161 
162 /**
163  * 创建一个 xml 对象
164  * @return {ACL_XML3*} 新创建的 xml 对象
165  */
166 ACL_API ACL_XML3 *acl_xml3_alloc(void);
167 
168 /**
169  * 创建一个 xml 对象,该 xml 对象及所有的内部内存分配都在该内存池上进行分配
170  * @param dbuf {ACL_DBUF_POOL*} 内存池对象,当该针对非 NULL 时,则 xml 对象
171  * 及所属节点内存在其基础上进行分配,否则,内部自动创建隶属于 xml 的内存池
172  * @return {ACL_XML3*} 新创建的 xml 对象
173  */
175 
176 /**
177  * 将某一个 ACL_XML3_NODE 节点作为一个 XML 对象的根节点,从而可以方便地遍历出该
178  * 节点各级子节点(在遍历过程中的所有节点不含本节点自身),该遍历方式有别于单独
179  * 遍历某一个 ACL_XML3_NODE 节点时仅能遍历其一级子节点的情形
180  * @param xml {ACL_XML3*} xml 对象
181  * @param node {ACL_XML3_NODE*} AXL_XML_NODE 节点
182  */
183 ACL_API void acl_xml3_foreach_init(ACL_XML3 *xml, ACL_XML3_NODE *node);
184 
185 /**
186  * 设置一个 xml 文档中是否允许有多个根 xml 节点,内部缺省支持多个根节点
187  * @param xml {ACL_XML3*} xml 对象
188  * @param on {int} 非 0 则允许,为 0 表示不允许,当禁止有多个根 xml 节点时,
189  * 则在解析时当遇到第一个根节点结束时便返回剩余的数据
190  */
191 ACL_API void acl_xml3_multi_root(ACL_XML3 *xml, int on);
192 
193 /**
194  * 对于 XML 单节点的情况, 是否允许可以没有 /, 如:
195  * <test id=111>, <test id=111 />, 当可以允许没有 / 则这两种写法
196  * 都是合法的,否则只有第二个写法是合法的,如果允许这种兼容性,则
197  * 会造成一定的性能损失
198  * @param xml {ACL_XML3*} xml 对象
199  * @param ignore {int} 如果非 0 表示单节点必须有 /
200  */
201 ACL_API void acl_xml3_slash(ACL_XML3 *xml, int ignore);
202 
203 /**
204  * 释放一个 xml 对象, 同时释放该对象里容纳的所有 xml 节点
205  * @param xml {ACL_XML3*} xml 对象
206  * @return {int} 返回释放的 xml 节点个数
207  */
208 ACL_API int acl_xml3_free(ACL_XML3 *xml);
209 
210 /**
211  * 重置 XML 解析器对象
212  * @param xml {ACL_XML3*} xml 对象
213  */
214 ACL_API void acl_xml3_reset(ACL_XML3 *xml);
215 
216 /*------------------------- in acl_xml3_parse.c ----------------------------*/
217 
218 /**
219  * 解析 xml 数据, 并持续地自动生成 xml 节点树
220  * @param xml {ACL_XML3*} xml 对象
221  * @param data {char*} 以 '\0' 结尾的数据字符串, 可以是完整的 xml 数据;
222  * 也可以是不完整的 xml 数据, 允许循环调用此函数, 将不完整数据持续地输入
223  * @return {char*} 当通过 acl_xml3_multi_root 允许一个 xml 文档中在在
224  * 多个根 xml 节点时,该函数返回的地址的字节为 '\0'; 否则返回剩余的数据地址
225  * 包含非空字符串
226  * 注:也可以通过 acl_xml3_is_complete 判断是否解析完毕
227  */
228 ACL_API char *acl_xml3_update(ACL_XML3 *xml, char *data);
229 #define acl_xml3_parse acl_xml3_update
230 
231 /*------------------------- in acl_xml3_util.c -----------------------------*/
232 
233 /**
234  * 初始化类似于 input, br, hr 等的自闭合标签, 形成自闭合标签树, 以便于
235  * acl_xml3_tag_selfclosed 查询该树, 检查所给标签是否是保留的自闭合标签,
236  * 该函数只能被初始化一次, 也可以不初始化
237  */
238 ACL_API void acl_xml3_tag_init(void);
239 
240 /**
241  * 允许用户自己添加一些非自闭合的标签
242  * @param tag {const char*} 标签名,注意标签长度不得大于 254 个字节
243  */
244 ACL_API void acl_xml3_tag_add(const char *tag);
245 
246 /**
247  * 当调用 acl_xml3_tag_init 初始化保留的自闭合标签树后, 可以调用此函数判断所给
248  * 标签是否属于自闭合标签, 如果未调用 acl_xml3_tag_init, 则该函数永远返回 0
249  * @parma tag {const char*} 标签名称
250  * @return {int} 0: 表示否, 1: 表示是
251  */
252 ACL_API int acl_xml3_tag_selfclosed(const char *tag);
253 
254 /**
255  * 判断标签所属 xml 节点是否是叶节点, 叶节点没有子节点
256  * @param tag {const char*} 标签名
257  * @return {int} 0: 不是叶节点; 1: 是叶节点
258  */
259 ACL_API int acl_xml3_tag_leaf(const char *tag);
260 
261 /**
262  * 释放由 acl_xml3_getElementsByTagName, acl_xml3_getElementsByName,
263  * acl_xml3_getElementsByAttr 等函数返回的动态数组对象, 因为该动态数组中的
264  * 元素都是 ACL_XML3 对象中元素的引用, 所以释放掉该动态数组后, 只要 ACL_XML3
265  * 对象不释放, 则原来存于该数组中的元素依然可以使用.
266  * 但并不释放里面的 xml 节点元素
267  * @param a {ACL_ARRAY*} 动态数组对象
268  */
269 ACL_API void acl_xml3_free_array(ACL_ARRAY *a);
270 
271 /**
272  * 从 xml 对象中获得与所给标签名相同的 xml 第一个节点
273  * @param xml {ACL_XML3*} xml 对象
274  * @param tag {const char*} 标签名称
275  * @return {ACL_XML3_NODE*} 符合条件的 xml 节点, 若返回 NULL 则
276  * 表示没有符合条件的 xml 节点
277  */
279  ACL_XML3 *xml, const char *tag);
280 
281 /**
282  * 从 xml 对象中获得所有的与所给标签名相同的 xml 节点的集合
283  * @param xml {ACL_XML3*} xml 对象
284  * @param tag {const char*} 标签名称
285  * @return {ACL_ARRAY*} 符合条件的 xml 节点集合, 存于 动态数组中, 若返回 NULL 则
286  * 表示没有符合条件的 xml 节点, 非空值需要调用 acl_xml3_free_array 释放
287  */
289  ACL_XML3 *xml, const char *tag);
290 
291 /**
292  * 从 xml 对象中获得所有的与给定多级标签名相同的 xml 节点的集合
293  * @param xml {ACL_XML3*} xml 对象
294  * @param tags {const char*} 多级标签名,由 '/' 分隔各级标签名,如针对 xml 数据:
295  * <root> <first> <second> <third name="test1"> text1 </third> </second> </first>
296  * <root> <first> <second> <third name="test2"> text2 </third> </second> </first>
297  * <root> <first> <second> <third name="test3"> text3 </third> </second> </first>
298  * 可以通过多级标签名:root/first/second/third 一次性查出所有符合条件的节点
299  * @return {ACL_ARRAY*} 符合条件的 xml 节点集合, 存于 动态数组中, 若返回 NULL 则
300  * 表示没有符合条件的 xml 节点, 非空值需要调用 acl_xml3_free_array 释放
301  */
302 ACL_API ACL_ARRAY *acl_xml3_getElementsByTags(ACL_XML3 *xml, const char *tags);
303 
304 /**
305  * 从 xml 对象中获得所有的与给定属性名 name 的属性值相同的 xml 节点元素集合
306  * @param xml {ACL_XML3*} xml 对象
307  * @param value {const char*} 属性名为 name 的属性值
308  * @return {ACL_ARRAY*} 符合条件的 xml 节点集合, 存于 动态数组中, 若返回 NULL 则
309  * 表示没有符合条件的 xml 节点, 非空值需要调用 acl_xml3_free_array 释放
310  */
311 ACL_API ACL_ARRAY *acl_xml3_getElementsByName(ACL_XML3 *xml, const char *value);
312 
313 /**
314  * 从 xml 对象中获得所有给定属性名及属性值的 xml 节点元素集合
315  * @param xml {ACL_XML3*} xml 对象
316  * @param name {const char*} 属性名
317  * @param value {const char*} 属性值
318  * @return {ACL_ARRAY*} 符合条件的 xml 节点集合, 存于 动态数组中, 若返回 NULL 则
319  * 表示没有符合条件的 xml 节点, 非空值需要调用 acl_xml3_free_array 释放
320  */
322  const char *name, const char *value);
323 
324 /**
325  * 从 xml 对象中获得指定 id 值的 xml 节点元素的某个属性对象
326  * @param xml {ACL_XML3*} xml 对象
327  * @param id {const char*} id 值
328  * @return {ACL_XML3_ATTR*} 某 xml 节点的某个属性对象, 若返回 NULL 则表示
329  * 没有符合条件的属性, 返回值不需要释放
330  */
331 ACL_API ACL_XML3_ATTR *acl_xml3_getAttrById(ACL_XML3 *xml, const char *id);
332 
333 /**
334  * 从 xml 对象中获得指定 id 值的 xml 节点元素的某个属性值
335  * @param xml {ACL_XML3*} xml 对象
336  * @param id {const char*} id 值
337  * @return {const char*} 某 xml 节点的某个属性值, 若返回 NULL 则表示没有符合
338  * 条件的属性
339  */
340 ACL_API const char *acl_xml3_getAttrValueById(ACL_XML3 *xml, const char *id);
341 
342 /**
343  * 从 xml 对象中获得指定 id 值的 xml 节点元素
344  * @param xml {ACL_XML3*} xml 对象
345  * @param id {const char*} id 值
346  * @return {ACL_XML3_NODE*} xml 节点元素, 若返回 NULL 则表示没有符合
347  * 条件的 xml 节点, 返回值不需要释放
348  */
349 ACL_API ACL_XML3_NODE *acl_xml3_getElementById(ACL_XML3 *xml, const char *id);
350 
351 /**
352  * 从 xml 对象中提取有在 ? ! 等开头的节点
353  * @param xml {ACL_XML3*} xml 对象
354  * @param tag {const char*} 标签名
355  * @return {ACL_XML3_NODE*} xml 节点元素, 若返回 NULL 则表示没有符合
356  * 条件的 xml 节点, 返回值不需要释放
357  */
358 ACL_API ACL_XML3_NODE *acl_xml3_getElementMeta(ACL_XML3 *xml, const char *tag);
359 
360 /**
361  * 获得 xml 的字符集编码格式
362  * @param xml {ACL_XML3*} xml 对象
363  * @return {const char*} 返回字符集编码格式,返回 NULL 时表示没有该属性
364  */
365 ACL_API const char *acl_xml3_getEncoding(ACL_XML3 *xml);
366 
367 /**
368  * 获得 xml 数据的类型,如:text/xsl
369  * @param xml {ACL_XML3*} xml 对象
370  * @return {const char*} 返回 NULL 表示没有该属性
371  */
372 ACL_API const char *acl_xml3_getType(ACL_XML3 *xml);
373 
374 /**
375  * 从 xml 节点中获得指定属性名的属性对象
376  * @param node {ACL_XML3_NODE*} xml 节点
377  * @param name {const char*} 属性名称
378  * @return {ACL_XML3_ATTR*} 属性对象, 为空表示不存在, 返回值不需要释放
379  */
381  const char *name);
382 
383 /**
384  * 从 xml 节点中获得指定属性名的属性值
385  * @param node {ACL_XML3_NODE*} xml 节点
386  * @param name {const char*} 属性名称
387  * @return {const char*} 属性值, 为空表示不存在
388  */
389 ACL_API const char *acl_xml3_getElementAttrVal(
390  ACL_XML3_NODE *node, const char *name);
391 
392 /**
393  * 从 xml 节点删除某个属性对象, 如果该属性为 id 属性, 则同时会从 xml->id_table 中删除
394  * @param node {ACL_XML3_NODE*} xml 节点
395  * @param name {const char*} 属性名称
396  * @return {int} 0 表示删除成功, -1: 表示删除失败(有可能是该属性不存在)
397  */
398 ACL_API int acl_xml3_removeElementAttr(ACL_XML3_NODE *node, const char *name);
399 
400 #if 0
401 /**
402  * 给 xml 节点添加属性, 如果该属性名已存在, 则用新的属性值替换其属性值, 否则
403  * 创建并添加新的属性对象
404  * @param node {ACL_XML3_NODE*} xml 节点
405  * @param name {const char*} 属性名称
406  * @param value {const char*} 属性值
407  * @return {ACL_XML3_ATTR*} 返回该属性对象(有可能是原来的, 也有可能是新的),
408  * 返回值不需释放
409  */
410 ACL_API ACL_XML3_ATTR *acl_xml3_addElementAttr(ACL_XML3_NODE *node,
411  const char *name, const char *value);
412 
413 /**
414  * 将标签名及节点文本做为参数创建 xml 节点,该函数主要用在构建 xml 对象时
415  * @param xml {ACL_XML3*} xml 对象,该对象应该是由 acl_xml3_alloc 创建的
416  * @param tagname {const char*} 标签名,必须非空且字符串长度大于 0
417  * @param text {const char*} 节点的文本内容,可以为空
418  * @return {ACL_XML3_NODE*} 新创建的 xml 节点,该返回永远返回非空,如果输入
419  * 参数非法则会导致内部自动产生断言
420  */
421 ACL_API ACL_XML3_NODE *acl_xml3_create_node(ACL_XML3 *xml,
422  const char *tagname, const char *text);
423 
424 /**
425  * 给一个 xml 节点添加属性,该函数主要用在构建 xml 对象时
426  * @param node {ACL_XML3_NODE*} 由 acl_xml3_create_node 创建的节点
427  * @param name {const char*} 属性名,必须为非空字符串且字符串长度大于 0
428  * @param value {const char*} 属性值,可以为空
429  * @return {ACL_XML3_ATTR*} xml 节点的属性对象,当输入参数非法时该函数
430  * 内部自动产生断言
431  */
432 ACL_API ACL_XML3_ATTR *acl_xml3_node_add_attr(ACL_XML3_NODE *node,
433  const char *name, const char *value);
434 
435 /**
436  * 给一个 xml 节点添加一组属性,该函数主要用在构建 xml 对象时
437  * @param node {ACL_XML3_NODE*} 由 acl_xml3_create_node 创建的节点
438  * @param ... 一组属性,遇到 NULL 时表示结束,如:
439  * {name1}, {value1}, {name2}, {value2}, ... NULL
440  */
441 ACL_API void acl_xml3_node_add_attrs(ACL_XML3_NODE *node, ...);
442 
443 /**
444  * 给一个 xml 节点添加文本内容,该函数主要用在构建 xml 对象时
445  * @param node {ACL_XML3_NODE*} 由 acl_xml3_create_node 创建的节点
446  * @param text {const char*} 文本内容
447  */
448 ACL_API void acl_xml3_node_set_text(ACL_XML3_NODE *node, const char *text);
449 
450 /**
451  * 将 xml 对象转成字符串内容
452  * @param xml {ACL_XML3*} xml 对象
453  * @param buf {ACL_VSTRING*} 存储结果集的缓冲区,当该参数为空时则函数内部会
454  * 自动分配一段缓冲区,应用用完后需要释放掉;非空函数内部会直接将结果存储其中
455  * @return {ACL_VSTRING*} xml 对象转换成字符串后的存储缓冲区,该返回值永远非空,
456  * 使用者可以通过 ACL_VSTRING_LEN(x) 宏来判断内容是否为空,返回的 ACL_VSTRING
457  * 指针如果为该函数内部创建的,则用户名必须用 acl_vstring_free 进行释放
458  */
459 ACL_API ACL_VSTRING* acl_xml3_build(ACL_XML3* xml, ACL_VSTRING *buf);
460 
461 /**
462  * 将 xml 对象转储于指定流中,注:该转储信息仅为调试用的数据
463  * @param xml {ACL_XML3*} xml 对象
464  * @param fp {ACL_VSTREAM*} 流对象
465  */
466 ACL_API void acl_xml3_dump(ACL_XML3 *xml, ACL_VSTREAM *fp);
467 
468 /**
469  * 将 xml 对象转存于指定缓冲区中,注:该转储信息仅为调试用的数据
470  * @param xml {ACL_XML3*} xml 对象
471  * @param buf {ACL_VSTRING*} 缓冲区, 需要用户自己分配空间
472  */
473 ACL_API void acl_xml3_dump2(ACL_XML3 *xml, ACL_VSTRING *buf);
474 
475 #endif
476 
477 /***************************************************************************/
478 /* 以下为更为低级的接口, 用户可以根据需要调用以下接口 */
479 /***************************************************************************/
480 
481 /*----------------------------- in acl_xml3.c ------------------------------*/
482 
483 /**
484  * 创建 xml 节点的属性
485  * @param node {ACL_XML3_NODE*} xml 节点
486  * @return {ACL_XML3_ATTR*} 新创建的节点属性
487  */
489 
490 /**
491  * 创建一个 xml 节点
492  * @param xml {ACL_XML3*} xml 对象
493  * @return {ACL_XML3_NODE*} xml 节点对象
494  */
496 
497 /**
498  * 将某个 xml 节点及其子节点从 xml 对象中删除, 并释放该节点及其子节点所占空间
499  * 函数来释放该 xml 节点所占内存
500  * @param node {ACL_XML3_NODE*} xml 节点
501  * @return {int} 返回删除的节点个数
502  */
503 ACL_API int acl_xml3_node_delete(ACL_XML3_NODE *node);
504 
505 /**
506  * 向某个 xml 节点添加兄弟节点(该兄弟节点必须是独立的 xml 节点)
507  * @param node1 {ACL_XML3_NODE*} 向本节点添加 xml 节点
508  * @param node2 {ACL_XML3_NODE*} 新添加的兄弟 xml 节点
509  */
510 ACL_API void acl_xml3_node_append(ACL_XML3_NODE *node1, ACL_XML3_NODE *node2);
511 
512 /**
513  * 将某个 xml 节点作为子节点加入某父 xml 节点中
514  * @param parent {ACL_XML3_NODE*} 父节点
515  * @param child {ACL_XML3_NODE*} 子节点
516  */
517 ACL_API void acl_xml3_node_add_child(ACL_XML3_NODE *parent, ACL_XML3_NODE *child);
518 
519 /**
520  * 获得某个 xml 节点的父节点
521  * @param node {ACL_XML3_NODE*} xml 节点
522  * @return {ACL_XML3_NODE*} 父节点, 如果为 NULL 则表示其父节点不存在
523  */
525 
526 /**
527  * 获得某个 xml 节点的后一个兄弟节点
528  * @param node {ACL_XML3_NODE*} xml 节点
529  * @return {ACL_XML3_NODE*} 给定 xml 节点的后一个兄弟节点, 若为NULL则表示不存在
530  */
532 
533 /**
534  * 获得某个 xml 节点的前一个兄弟节点
535  * @param node {ACL_XML3_NODE*} xml 节点
536  * @return {ACL_XML3_NODE*} 给定 xml 节点的前一个兄弟节点, 若为NULL则表示不存在
537  */
539 
540 #ifdef __cplusplus
541 }
542 #endif
543 #endif
ACL_API char * acl_xml3_update(ACL_XML3 *xml, char *data)
ACL_XML3_NODE * parent
Definition: acl_xml3.h:45
int node_cnt
Definition: acl_xml3.h:105
ACL_RING node
Definition: acl_xml3.h:51
ACL_XML3_NODE * node
Definition: acl_xml3.h:21
ACL_API ACL_XML3_NODE * acl_xml3_node_prev(ACL_XML3_NODE *node)
ACL_API void acl_xml3_node_append(ACL_XML3_NODE *node1, ACL_XML3_NODE *node2)
const char * id
Definition: acl_xml3.h:39
ACL_API ACL_XML3_ATTR * acl_xml3_getAttrById(ACL_XML3 *xml, const char *id)
HTTP_API void const char * name
Definition: lib_http.h:620
ACL_API ACL_XML3_NODE * acl_xml3_node_next(ACL_XML3_NODE *node)
char * name
Definition: acl_xml3.h:22
size_t name_size
Definition: acl_xml3.h:25
char * value
Definition: acl_xml3.h:23
ACL_API ACL_ARRAY * acl_xml3_getElementsByTags(ACL_XML3 *xml, const char *tags)
int backslash
Definition: acl_xml3.h:30
ACL_API void acl_xml3_slash(ACL_XML3 *xml, int ignore)
ACL_API int acl_xml3_is_closure(ACL_XML3 *xml)
ACL_API void acl_xml3_reset(ACL_XML3 *xml)
ACL_API ACL_XML3_ATTR * acl_xml3_getElementAttr(ACL_XML3_NODE *node, const char *name)
ACL_API void acl_xml3_free_array(ACL_ARRAY *a)
ACL_XML3 * xml
Definition: acl_xml3.h:50
ACL_API void acl_xml3_node_add_child(ACL_XML3_NODE *parent, ACL_XML3_NODE *child)
ACL_RING children
Definition: acl_xml3.h:46
ACL_XML3_ATTR * curr_attr
Definition: acl_xml3.h:52
ACL_API ACL_ARRAY * acl_xml3_getElementsByTagName(ACL_XML3 *xml, const char *tag)
ACL_API ACL_XML3_NODE * acl_xml3_getFirstElementByTagName(ACL_XML3 *xml, const char *tag)
ACL_API int acl_xml3_tag_selfclosed(const char *tag)
ACL_API ACL_XML3 * acl_xml3_alloc(void)
ACL_XML3_NODE * root
Definition: acl_xml3.h:107
ACL_API ACL_ARRAY * acl_xml3_getElementsByName(ACL_XML3 *xml, const char *value)
ACL_API ACL_XML3_NODE * acl_xml3_node_alloc(ACL_XML3 *xml)
ACL_API void acl_xml3_multi_root(ACL_XML3 *xml, int on)
size_t rtag_size
Definition: acl_xml3.h:38
size_t ltag_size
Definition: acl_xml3.h:37
size_t dbuf_keep
Definition: acl_xml3.h:115
ACL_API const char * acl_xml3_getElementAttrVal(ACL_XML3_NODE *node, const char *name)
ACL_API ACL_XML3_NODE * acl_xml3_node_parent(ACL_XML3_NODE *node)
ACL_API int acl_xml3_tag_leaf(const char *tag)
ACL_DBUF_POOL * dbuf_inner
Definition: acl_xml3.h:114
ACL_ARRAY * attr_list
Definition: acl_xml3.h:44
ACL_API int acl_xml3_free(ACL_XML3 *xml)
int depth
Definition: acl_xml3.h:104
struct ACL_DBUF_POOL ACL_DBUF_POOL
Definition: acl_dbuf_pool.h:8
ACL_API void acl_xml3_tag_add(const char *tag)
int root_cnt
Definition: acl_xml3.h:106
ACL_XML3_NODE * curr_node
Definition: acl_xml3.h:112
ACL_API const char * acl_xml3_getAttrValueById(ACL_XML3 *xml, const char *id)
size_t value_size
Definition: acl_xml3.h:26
ACL_API ACL_XML3_ATTR * acl_xml3_attr_alloc(ACL_XML3_NODE *node)
unsigned flag
Definition: acl_xml3.h:117
ACL_API ACL_XML3 * acl_xml3_dbuf_alloc(ACL_DBUF_POOL *dbuf)
ACL_API const char * acl_xml3_getEncoding(ACL_XML3 *xml)
ACL_API int acl_xml3_is_complete(ACL_XML3 *xml, const char *tag)
ACL_API void acl_xml3_tag_init(void)
char meta[3]
Definition: acl_xml3.h:56
ACL_API void acl_xml3_foreach_init(ACL_XML3 *xml, ACL_XML3_NODE *node)
ACL_DBUF_POOL * dbuf
Definition: acl_xml3.h:113
ACL_API ACL_ARRAY * acl_xml3_getElementsByAttr(ACL_XML3 *xml, const char *name, const char *value)
char * rtag
Definition: acl_xml3.h:36
unsigned int flag
Definition: acl_xml3.h:58
char * ltag
Definition: acl_xml3.h:35
ACL_API const char * acl_xml3_getType(ACL_XML3 *xml)
size_t text_size
Definition: acl_xml3.h:42
char addr[1]
Definition: acl_xml3.h:110
ACL_API int acl_xml3_node_delete(ACL_XML3_NODE *node)
ACL_API ACL_XML3_NODE * acl_xml3_getElementMeta(ACL_XML3 *xml, const char *tag)
char * text
Definition: acl_xml3.h:41
ACL_API ACL_XML3_NODE * acl_xml3_getElementById(ACL_XML3 *xml, const char *id)
ACL_API int acl_xml3_removeElementAttr(ACL_XML3_NODE *node, const char *name)
ACL_HTABLE * id_table
Definition: acl_xml3.h:111