blob: d5005b5ff2065dcf1a650f188f93f1275aa62dac [file] [log] [blame]
yu.dongc33b3072024-08-21 23:14:49 -07001/** \file roxml.h
2 * \brief header for libroxml.so
3 *
4 * This is the header file used to develop some
5 * software using the libroxml.so library.
6 * \author blunderer <blunderer@blunderer.org>
7 * \date 23 Dec 2008
8 *
9 * Copyright (C) 2009 blunderer
10 *
11 * As a special exception to the LGPL v2.1 (below), the copyright holders of
12 * this library give you permission to statically link this library
13 * with independent modules to produce an executable, regardless of the license
14 * terms of these independent modules, and to copy and distribute the resulting
15 * executable under terms of your choice, provided that you also meet, for each
16 * linked independent module, the terms and conditions of the license of that
17 * module. The resulting executable may therefore be distributed without complying
18 * with the LGPL terms that state that recipients of your executable must be able
19 * to relink against modified versions of the library.
20 *
21 * This library is free software; you can redistribute it and/or
22 * modify it under the terms of the GNU Lesser General Public
23 * License as published by the Free Software Foundation; either
24 * version 2.1 of the License, or (at your option) any later version.
25 * The author added a static linking exception, see License.txt.
26 *
27 * This library is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
30 * Lesser General Public License for more details.
31 *
32 * You should have received a copy of the GNU Lesser General Public
33 * License along with this library; if not, write to the Free Software
34 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
35 */
36
37/*******************************************************************************
38 * ==========================================================================
39 * $Log$
40 *
41 * 01 28 2019 cs.huang
42 * [MOLY00381872] [VMOLY] XCAP merge from UMOLYE
43 * XCAP sync from UMOLYE (OA part)
44 *
45 * 12 28 2018 howen.pu
46 * [MOLY00374881] Gen95 XCAP - USIR
47 * Gen 95 USIR - For XCAP.
48 *
49 * 12 28 2018 howen.pu
50 * [MOLY00374881] Gen95 XCAP - USIR
51 *
52 * Gen 95 USIR - For XCAP.
53 *
54 *
55****************************************************************************/
56
57#ifndef ROXML_H
58#define ROXML_H
59
60#ifdef __cplusplus
61extern "C" {
62#endif
63
64/**
65 * \def ROXML_API
66 *
67 * part of the public API
68 */
69#define ROXML_API
70
71#ifndef ROXML_INT
72/** \typedef node_t
73 *
74 * \brief node_t structure
75 *
76 * This is the structure for a node. This struct is very
77 * little as it only contains offset for node in file and
78 * tree links
79 */
80typedef struct node node_t;
81#endif
82
83/**
84 * \def ROXML_INVALID_NODE
85 *
86 * constant for invalid nodes
87 */
88#define ROXML_INVALID_NODE 0x000
89
90/**
91 * \def ROXML_ATTR_NODE
92 *
93 * constant for attribute nodes
94 * \see roxml_add_node
95 */
96#define ROXML_ATTR_NODE 0x008
97
98/**
99 * \def ROXML_STD_NODE
100 *
101 * \deprecated
102 * constant for standard nodes
103 *
104 * \see roxml_add_node
105 *
106 */
107#define ROXML_STD_NODE 0x010
108
109/**
110 * \def ROXML_ELM_NODE
111 *
112 * constant for element nodes
113 * \see roxml_add_node
114 */
115#define ROXML_ELM_NODE 0x010
116
117/**
118 * \def ROXML_TXT_NODE
119 *
120 * constant for text nodes
121 * \see roxml_add_node
122 */
123#define ROXML_TXT_NODE 0x020
124
125/**
126 * \def ROXML_CMT_NODE
127 *
128 * constant for comment nodes
129 * \see roxml_add_node
130 */
131#define ROXML_CMT_NODE 0x040
132
133/**
134 * \def ROXML_PI_NODE
135 *
136 * constant for processing_intruction nodes
137 * \see roxml_add_node
138 */
139#define ROXML_PI_NODE 0x080
140
141/**
142 * \def ROXML_NS_NODE
143 *
144 * constant for namespace nodes
145 * \see roxml_add_node
146 */
147#define ROXML_NS_NODE 0x100
148
149/**
150 * \def ROXML_NSDEF_NODE
151 *
152 * constant for namespace definition nodes
153 * \see roxml_add_node
154 */
155#define ROXML_NSDEF_NODE (ROXML_NS_NODE | ROXML_ATTR_NODE)
156
157/**
158 * \def ROXML_CDATA_NODE
159 *
160 * constant for cdata nodes
161 * \see roxml_add_node
162 */
163#define ROXML_CDATA_NODE (ROXML_TXT_NODE | 0x200)
164
165/**
166 * \def ROXML_DOCTYPE_NODE
167 *
168 * constant for doctype nodes
169 * \see roxml_add_node
170 */
171#define ROXML_DOCTYPE_NODE 0x400
172
173/**
174 * \def ROXML_ALL_NODES
175 *
176 * constant for all types of nodes
177 * \see roxml_add_node
178 */
179#define ROXML_ALL_NODES (ROXML_PI_NODE | ROXML_CMT_NODE | ROXML_TXT_NODE | ROXML_ATTR_NODE | ROXML_ELM_NODE)
180
181/**
182 * \def ROXML_ALL_NODE
183 *
184 * constant for all types of nodes for backward compatibility
185 * \see roxml_add_node
186 */
187#define ROXML_ALL_NODE ROXML_ALL_NODES
188
189/**
190 * \def ROXML_NODE_TYPES
191 *
192 * constant for all nodes types
193 * \see roxml_get_types
194 */
195#define ROXML_NODE_TYPES 0x05f8
196
197/**
198 * \def RELEASE_ALL
199 *
200 * when used with roxml_release, release all memory allocated by current thread
201 * \see roxml_release
202 */
203#define RELEASE_ALL (void*)-1
204
205/**
206 * \def RELEASE_LAST
207 *
208 * when used with roxml_release, release last variable allocated
209 * \see roxml_release
210 *
211 * example:
212 * \code
213 * #include <stdio.h>
214 * #include <roxml.h>
215 * int main(void)
216 * {
217 * int len;
218 * node_t *root = roxml_load_doc("/tmp/doc.xml");
219 *
220 * // roxml_get_content allocate a buffer and store the content in it if no buffer was given
221 * printf("root content = '%s'\n", roxml_get_content(root, NULL, 0, &len));
222 *
223 * // release the last allocated buffer even if no pointer is maintained by the user
224 * roxml_release(RELEASE_LAST);
225 *
226 * // here no memory leak can occur.
227 *
228 * roxml_close(root);
229 * return 0;
230 * }
231 * \endcode
232 */
233#define RELEASE_LAST (void*)-2
234
235/**
236 * \def ROXML_INVALID_DOC
237 *
238 * constant for invalid documents
239 */
240#define ROXML_INVALID_DOC (node_t*)0
241
242/** \brief load function for buffers
243 *
244 * \fn node_t* roxml_load_buf(char *buffer);
245 * This function load a document by parsing all the corresponding nodes.
246 * The document must be contained inside the char * buffer given in parameter
247 * and remain valid until the roxml_close() function is called
248 * \param buffer the XML buffer to load
249 * \return the root node or ROXML_INVALID_DOC (NULL). errno is set to EINVAL in case of parsing error
250 * \see roxml_close
251 * \see roxml_load_fd
252 * \see roxml_load_doc
253 */
254ROXML_API node_t * roxml_load_buf(char *buffer);
255
256/** \brief load function for files
257 *
258 * \fn node_t* roxml_load_doc(char *filename);
259 * This function load a file document by parsing all the corresponding nodes
260 * \warning the file is not fully copied and thus, it should stay untouched until roxml_close is called on the corresponding XML tree.
261 * \param filename the XML document to load
262 * \return the root node or ROXML_INVALID_DOC (NULL). errno is set to EINVAL in case of parsing error
263 * \see roxml_close
264 * \see roxml_load_fd
265 * \see roxml_load_buf
266 */
267ROXML_API node_t * roxml_load_doc(char *filename);
268
269/** \brief load function for file descriptors
270 *
271 * \fn node_t* roxml_load_fd(int fd);
272 * This function load a document by parsing all the corresponding nodes
273 * \param fd the opened file descriptor to XML document to load
274 * \return the root node or ROXML_INVALID_DOC (NULL). errno is set to EINVAL in case of parsing error
275 * \see roxml_close
276 * \see roxml_load_doc
277 * \see roxml_load_buf
278 */
279ROXML_API node_t * roxml_load_fd(int fd);
280
281/** \brief unload function
282 *
283 * \fn void roxml_close(node_t *n);
284 * This function clear a document and all the corresponding nodes
285 * It release all memory allocated during roxml_load_doc or roxml_load_file or roxml_add_node.
286 * All nodes from the tree are not available anymore.
287 * \param n is any node of the tree to be cleaned
288 * \return void
289 * \see roxml_load_doc
290 * \see roxml_load_buf
291 * \see roxml_add_node
292 */
293ROXML_API void roxml_close(node_t *n);
294
295/** \brief next sibling getter function
296 *
297 * \fn node_t* roxml_get_next_sibling(node_t *n);
298 * This function returns the next sibling of a given node
299 * \param n is one node of the tree
300 * \return the next sibling node
301 */
302ROXML_API node_t * roxml_get_next_sibling(node_t *n);
303
304/** \brief prev sibling getter function
305 *
306 * \fn node_t* roxml_get_prev_sibling(node_t *n);
307 * This function returns the prev sibling of a given node
308 * \param n is one node of the tree
309 * \return the prev sibling node
310 */
311ROXML_API node_t * roxml_get_prev_sibling(node_t *n);
312
313/** \brief parent getter function
314 *
315 * \fn node_t* roxml_get_parent(node_t *n);
316 * This function returns the parent of a given node
317 * \param n is one node of the tree
318 * \return the parent node
319 */
320ROXML_API node_t * roxml_get_parent(node_t *n);
321
322/** \brief root getter function
323 *
324 * \fn node_t* roxml_get_root(node_t *n);
325 * This function returns the root of a tree containing the given node
326 * The root is defined as a virtual node that contains all first rank nodes if document is
327 * not a valid xml document:
328 * \verbatim
329<data1>
330 <item/>
331 <item/>
332</data1>
333<data2>
334 <item/>
335 <item/>
336</data2>
337\endverbatim
338 * will be processed successfully and the root node will have 2 children: data1 and data2
339 *
340 * if document was:
341 * \verbatim
342<?xml version="1.0">
343<doc>
344 <data1>
345 <item/>
346 <item/>
347 </data1>
348 <data2>
349 <item/>
350 <item/>
351 </data2>
352</doc>
353\endverbatim
354 * In this case, the node "doc" will be the root, and will contain 2 children: data1 and data2
355 *
356 * For a document to be valid, following conditions must be met:
357 * <ul>
358 * <li>the first node is a processing instruction with the string "xml" as target application.</li>
359 * <li>there is only one ELM node containing all document (but there may be several process-instructions or comments)</li>
360 * </ul>
361 * \param n is one node of the tree
362 * \return the root node
363 */
364ROXML_API node_t * roxml_get_root(node_t *n);
365
366/** \brief namespace getter function
367 *
368 * \fn node_t* roxml_get_ns(node_t *n);
369 * This function returns the namespace of a node
370 *
371 * \param n is one node of the tree
372 * \return the namespace or NULL if none are set for this node
373 * \see roxml_add_node
374 * \see roxml_set_ns
375 * \see roxml_get_nodes
376 *
377 * example:
378 * given the following xml file
379 * \verbatim
380<xml xmlns:test="http://www.test.org">
381 <test:item1 test:value1="3"/>
382</xml>
383\endverbatim
384 * \code
385 * #include <stdio.h>
386 * #include <roxml.h>
387 *
388 * int main(void)
389 * {
390 * node_t *root = roxml_load_doc("/tmp/doc.xml");
391 * node_t *xml = roxml_get_chld(root, NULL, 0);
392 * node_t *nsdef = roxml_get_attr(xml, NULL, 0);
393 * node_t *node1 = roxml_get_chld(xml, NULL, 0);
394 * node_t *attr1 = roxml_get_attr(node1, NULL, 0);
395 * node_t *node1_ns = roxml_get_ns(node1);
396 * node_t *attr1_ns = roxml_get_ns(attr1);
397 *
398 * // here node1_ns and attr1_ns are the "test:" namespace
399 * if(node1_ns == nsdef) {
400 * printf("got the correct namespace node for elem\n");
401 * }
402 * if(attr1_ns == nsdef) {
403 * printf("got the correct namespace node for attr\n");
404 * }
405 * if(strcmp(roxml_get_name(node1_ns, NULL, 0), "test") == 0) {
406 * printf("got the correct namespace alias\n");
407 * }
408 * if(strcmp(roxml_get_content(node1_ns, NULL, 0, NULL), "http://www.test.org") == 0) {
409 * printf("got the correct namespace\n");
410 * }
411 *
412 * roxml_close(root);
413 * return 0;
414 * }
415 *
416 * \endcode
417 */
418ROXML_API node_t * roxml_get_ns(node_t *n);
419
420/** \brief namespace setter function
421 *
422 * \fn node_t* roxml_set_ns(node_t *n, node_t *ns);
423 * This function set the namespace of a node to the given namespace definition.
424 * The namespace must be previously defined in the xml tree in an ancestor of node n.
425 *
426 * \param n is one node of the tree
427 * \param ns is one nsdef node of the tree
428 * \return the node or ROXML_INVALID_DOC (NULL) if ns cannot be set
429 * \see roxml_add_node
430 * \see roxml_get_ns
431 * \see roxml_get_nodes
432 *
433 * \warning: Setting a namespace to a node is recursif:
434 * - it will update all element and attribute that are descendant from current node
435 * - namespace will be applied to all new node added as descendant as current node
436 */
437ROXML_API node_t * roxml_set_ns(node_t *n, node_t * ns);
438
439/** \brief comment getter function
440 *
441 * \fn node_t* roxml_get_cmt(node_t *n, int nth);
442 * This function returns the nth comment of a node
443 *
444 * \param n is one node of the tree
445 * \param nth is the id of the cmt to get
446 * \return the comment corresponding to id
447 * \see roxml_get_cmt_nb
448 * \see roxml_get_nodes
449 *
450 * example:
451 * given the following xml file
452 * \verbatim
453<xml>
454 <item1/>
455 <!--comment1-->
456 <!--comment2-->
457 <item2/>
458 <item3/>
459</xml>
460\endverbatim
461 * \code
462 * #include <stdio.h>
463 * #include <roxml.h>
464 *
465 * int main(void)
466 * {
467 * node_t *root = roxml_load_doc("/tmp/doc.xml");
468 * node_t *xml = roxml_get_chld(root, NULL, 0);
469 * node_t *cmt1 = roxml_get_cmt(xml, 0);
470 * node_t *cmt2 = roxml_get_cmt(xml, 1);
471 *
472 * // here cmt1 is the "comment1" node
473 * if(strcmp(roxml_get_content(cmt1, NULL, 0, NULL), "comment1") == 0) {
474 * printf("got the first comment\n");
475 * }
476 * // and cmt2 is the "comment2" node
477 * if(strcmp(roxml_get_content(cmt2, NULL, 0, NULL), "comment2") == 0) {
478 * printf("got the second comment\n");
479 * }
480 *
481 * roxml_close(root);
482 * return 0;
483 * }
484 *
485 * \endcode
486 */
487ROXML_API node_t * roxml_get_cmt(node_t *n, int nth);
488
489/** \brief comments number getter function
490 *
491 * \fn int roxml_get_cmt_nb(node_t *n);
492 * This function return the number of comments for a given node
493 * \param n is one node of the tree
494 * \return the number of comments
495 * \see roxml_get_cmt_nb
496 * \see roxml_get_nodes
497 */
498ROXML_API int roxml_get_cmt_nb(node_t *n);
499
500/** \brief chld getter function
501 *
502 * \fn node_t* roxml_get_chld(node_t *n, char * name, int nth);
503 * This function returns a given chld of a node etheir by name, or the nth child.
504 *
505 * \param n is one node of the tree
506 * \param name is the name of the child to get
507 * \param nth is the id of the chld to get
508 * \return the chld corresponding to name or id (if both are set, name is used)
509 * \see roxml_get_chld_nb
510 *
511 * example:
512 * given the following xml file
513 * \verbatim
514<xml>
515 <item1/>
516 <item2/>
517 <item3/>
518</xml>
519\endverbatim
520 * \code
521 * #include <stdio.h>
522 * #include <roxml.h>
523 *
524 * int main(void)
525 * {
526 * node_t *root = roxml_load_doc("/tmp/doc.xml");
527 *
528 * node_t *child_by_name = roxml_get_chld(root, "item2", 0);
529 * node_t *child_by_nth = roxml_get_chld(root, NULL, 2);
530 *
531 * // here child_by_name == child_by_nth
532 * if(child_by_name == child_by_nth) {
533 * printf("Nodes are equal\n");
534 * }
535 *
536 * roxml_close(root);
537 * return 0;
538 * }
539 * \endcode
540 */
541ROXML_API node_t * roxml_get_chld(node_t *n, char *name, int nth);
542
543/** \brief chlds number getter function
544 *
545 * \fn int roxml_get_chld_nb(node_t *n);
546 * This function return the number of chlidren for a given node
547 * \param n is one node of the tree
548 * \return the number of chlildren
549 */
550ROXML_API int roxml_get_chld_nb(node_t *n);
551
552/** \brief process-instruction getter function
553 *
554 * \fn node_t* roxml_get_pi(node_t *n, int nth);
555 * This function returns the nth process-instruction of a node.
556 *
557 * \param n is one node of the tree
558 * \param nth is the id of the pi to get
559 * \return the process-instruction corresponding to id
560 * \see roxml_get_pi_nb
561 * \see roxml_get_nodes
562 *
563 * example:
564 * given the following xml file
565 * \verbatim
566<xml>
567 <item1/>
568 <?test value="2"?>
569 <?test param="3"?>
570 <item2/>
571 <item3/>
572</xml>
573\endverbatim
574 * \code
575 * #include <stdio.h>
576 * #include <roxml.h>
577 *
578 * int main(void)
579 * {
580 * node_t *root = roxml_load_doc("/tmp/doc.xml");
581 * node_t *xml = roxml_get_chld(root, NULL, 0);
582 * node_t *pi1 = roxml_get_pi(xml, 0);
583 * node_t *pi2 = roxml_get_pi(xml, 1);
584 *
585 * // here pi1 is the <?value="2"?> node
586 * if(strcmp(roxml_get_content(pi1, NULL, 0, NULL), "value=\"2\"") == 0) {
587 * printf("got the first process-instruction\n");
588 * }
589 * // and pi2 is the <?param="3"?> node
590 * if(strcmp(roxml_get_content(pi2, NULL, 0, NULL), "param=\"3\"") == 0) {
591 * printf("got the second process-instruction\n");
592 * }
593 *
594 * roxml_close(root);
595 * return 0;
596 * }
597 *
598 * \endcode
599 */
600ROXML_API node_t * roxml_get_pi(node_t *n, int nth);
601
602/** \brief process-instruction number getter function
603 *
604 * \fn int roxml_get_pi_nb(node_t *n);
605 * This function return the number of process-instruction in a given node
606 * \param n is one node of the tree
607 * \return the number of process-instructions
608 * \see roxml_get_pi
609 * \see roxml_get_nodes_nb
610 */
611ROXML_API int roxml_get_pi_nb(node_t *n);
612
613/** \brief name getter function
614 *
615 * \fn char* roxml_get_name(node_t *n, char * buffer, int size);
616 * This function return the name of the node or fill the current buffer with it if not NULL.
617 * if name is NULL, the function will allocate a buffer that user should free using
618 * roxml_release when no longer needed.
619 * depending on node type it will return:
620 * <ul>
621 * <li> ROXML_ELM_NODE: returns the node name</li>
622 * <li> ROXML_ATTR_NODE: returns the attribute name</li>
623 * <li> ROXML_PI_NODE: returns the process-instruction targeted application</li>
624 * <li> ROXML_TXT_NODE: returns NULL (or empty string if you provided a buffer in buffer param)</li>
625 * <li> ROXML_CMT_NODE: returns NULL (or empty string if you provided a buffer in buffer param)</li>
626 * <li> ROXML_NS_NODE: returns the namespace alias associated with the ns node </li>
627 * </ul>
628 * Be carreful as if your buffer is too short for the returned string, it will be truncated
629 * \param n is one node of the tree
630 * \param buffer a buffer pointer or NULL if has to be auto allocated
631 * \param size the size of buffer pointed by buffer if not NULL
632 * \return the name of the node (return our buffer pointer if it wasn't NULL)
633 * \see roxml_release
634 */
635ROXML_API char * roxml_get_name(node_t *n, char *buffer, int size);
636
637/** \brief content getter function
638 *
639 * \fn char * roxml_get_content(node_t *n, char * buffer, int bufsize, int * size);
640 *
641 * This function returns the content of a node.;
642 * if the returned pointer is NULL then the node either has no content or this function is irrelevant for this kind of node.
643 * depending on node type it will return:
644 * <ul>
645 * <li> ROXML_ELM_NODE: returns the concatenation of all direct text node children</li>
646 * <li> ROXML_ATTR_NODE: returns the attribute value</li>
647 * <li> ROXML_PI_NODE: returns the process-instruction instruction</li>
648 * <li> ROXML_TXT_NODE: returns the text content of the node</li>
649 * <li> ROXML_CMT_NODE: returns the text content of the comment</li>
650 * <li> ROXML_NS_NODE: returns the namespace definition (usually an URL)</li>
651 * </ul>
652 * returned string should be freed using roxml_release when not used anymore
653 * \param n is one node of the tree
654 * \param buffer is the buffer where result will be written or NULL for internal allocation
655 * \param bufsize the size if using custom buffer
656 * \param size the actual size of copied result. returned size should be less that buffer size since roxml_get_content
657 * will add the \0. if buffer was not NULL and size == buf_size, then given buffer was too small and node content was truncated
658 * \return the text content
659 * \see roxml_release
660 */
661ROXML_API char * roxml_get_content(node_t *n, char *buffer, int bufsize, int *size);
662
663/** \brief number of nodes getter function
664 *
665 * \fn int roxml_get_nodes_nb(node_t *n, int type);
666 *
667 * This function returns the number of nodes matching type flag contained in a given node
668 * all other roxml_get_*_nb are wrapper to this
669 * \param n is one node of the tree
670 * \param type is the bitmask of node types we want to consider
671 * \return the number of nodes
672 * \see roxml_get_attr_nb
673 * \see roxml_get_chld_nb
674 * \see roxml_get_txt_nb
675 * \see roxml_get_cmt_nb
676 * \see roxml_get_pi_nb
677 *
678 * example:
679 * given the following xml file
680 * \verbatim
681<xml>
682 <!-- comment -->
683 <?value="2"?>
684 <product id="42" class="item"/>
685 <product id="43" class="item"/>
686</xml>
687\endverbatim
688 * \code
689 * #include <stdio.h>
690 * #include <roxml.h>
691 *
692 * int main(void)
693 * {
694 * node_t *root = roxml_load_doc("/tmp/doc.xml");
695 *
696 * int all_nodes_1 = roxml_get_nodes_nb(root, ROXML_ELM_NODE | ROXML_CMT_NODE | ROXML_PI_NODE | ROXML_TXT_NODE | ROXML_ATTR_NODE);
697 * int all_nodes_2 = roxml_get_nodes_nb(root, ROXML_ALL_NODES);
698 *
699 * // here all_nodes_1 == all_nodes_2
700 * if(all_nodes_1 == all_nodes_2) {
701 * printf("%d Nodes are contained in root\n", all_nodes_1);
702 * }
703 *
704 * // let's count elm node (== children)
705 * int elm_nodes1 = roxml_get_nodes_nb(root, ROXML_ELM_NODE);
706 * int elm_nodes2 = roxml_get_chld_nb(root);
707 * // here elm_nodes1 == elm_nodes2 == 2
708 * if(elm_nodes1 == elm_nodes2) {
709 * printf("%d ELM Nodes are contained in root\n", elm_nodes_1);
710 * }
711 *
712 * // we can also count all node except elm nodes, doing:
713 * int almost_all_nodes = roxml_get_nodes_nb(root, ROXML_ALL_NODES & ~ROXML_ELM_NODE);
714 * // here almost_all_nodes = 2 since we have one comment node and one processing-instruction node
715 * if(almost_all_nodes == 2) {
716 * printf("%d non ELM Nodes are contained in root\n", almost_all_nodes_1);
717 * }
718 *
719 * roxml_close(root);
720 * return 0;
721 * }
722 * \endcode
723 */
724ROXML_API int roxml_get_nodes_nb(node_t *n, int type);
725
726/** \brief nodes getter function
727 *
728 * \fn char* roxml_get_nodes(node_t *n, int type, char * name, int nth);
729 * This function get the nth node matching type contained in a node, or the first node named name.
730 * All other roxml_get_* are wrapper to this function.
731 * When asking for several node type (let say ROXML_ALL_NODES), all ROXML_ATTR_NODE will be
732 * placed first, then, all other nodes will come mixed, depending on xml document order.
733 *
734 * \param n is one node of the tree
735 * \param type is the bitmask of node types we want to consider
736 * \param name is the name of the child to get. This parameter is only relevant for node with types: \ref ROXML_ELM_NODE, \ref ROXML_ATTR_NODE, \ref ROXML_PI_NODE
737 * \param nth the id of attribute to read
738 * \return the node corresponding to name or id (if both are set, name is used)
739 * \see roxml_get_attr
740 * \see roxml_get_chld
741 * \see roxml_get_txt
742 * \see roxml_get_cmt
743 * \see roxml_get_pi
744 */
745ROXML_API node_t * roxml_get_nodes(node_t *n, int type, char *name, int nth);
746
747/** \brief number of attribute getter function
748 *
749 * \fn int roxml_get_attr_nb(node_t *n);
750 *
751 * This function returns the number of attributes for a given node
752 * \param n is one node of the tree
753 * \return the number of attributes in node
754 */
755ROXML_API int roxml_get_attr_nb(node_t *n);
756
757/** \brief attribute getter function
758 *
759 * \fn node_t* roxml_get_attr(node_t *n, char * name, int nth);
760 * This function get the nth attribute of a node.
761 * \param n is one node of the tree
762 * \param name is the name of the attribute to get
763 * \param nth the id of attribute to read
764 * \return the attribute corresponding to name or id (if both are set, name is used)
765 *
766 * example:
767 * given the following xml file
768 * \verbatim
769<xml>
770 <product id="42" class="item"/>
771</xml>
772\endverbatim
773 * \code
774 * #include <stdio.h>
775 * #include <roxml.h>
776 *
777 * int main(void)
778 * {
779 * node_t *root = roxml_load_doc("/tmp/doc.xml");
780 * node_t *item1 = roxml_get_chld(root, NULL, 0);
781 * node_t *item2 = roxml_get_chld(item1, NULL, 0);
782 *
783 * node_t *attr_by_name = roxml_get_attr(item2, "id", 0);
784 * node_t *attr_by_nth = roxml_get_attr(item2, NULL, 0);
785 *
786 * // here attr_by_name == attr_by_nth
787 * if(attr_by_name == attr_by_nth) {
788 * printf("Nodes are equal\n");
789 * }
790 *
791 * roxml_close(root);
792 * return 0;
793 * }
794 * \endcode
795 */
796ROXML_API node_t * roxml_get_attr(node_t *n, char *name, int nth);
797
798/** \brief exec path function
799 *
800 * \fn roxml_xpath(node_t *n, char * path, int *nb_ans);
801 * This function return a node set (table of nodes) corresponding to a given xpath.
802 * resulting node set should be roxml_release when not used anymore (but not individual nodes)
803 * \param n is one node of the tree
804 * \param path the xpath to use
805 * \param nb_ans the number of results
806 * \return the node table or NULL
807 *
808 * handled xpath are described in \ref xpath
809 */
810ROXML_API node_t ** roxml_xpath(node_t *n, char *path, int *nb_ans);
811
812/** \brief node type function
813 *
814 * \fn roxml_get_type(node_t *n);
815 * This function tells if a node is an \ref ROXML_ATTR_NODE, \ref ROXML_TXT_NODE, \ref ROXML_PI_NODE, \ref ROXML_CMT_NODE or \ref ROXML_ELM_NODE.
816 * Warning: ROXML_CDATA_NODE are special. They return a type as ROXML_TXT_NODE.
817 * \param n is the node to test
818 * \return the node type
819 */
820ROXML_API int roxml_get_type(node_t *n);
821
822/** \brief node get position function
823 *
824 * \fn roxml_get_node_position(node_t *n);
825 * This function tells the index of a node between all its siblings homonyns.
826 * \param n is the node to test
827 * \return the postion between 1 and N
828 */
829ROXML_API int roxml_get_node_position(node_t *n);
830
831/** \brief memory cleanning function
832 *
833 * \fn roxml_release(void * data);
834 * This function release the memory pointed by pointer
835 * just like free would but for memory allocated with roxml_malloc.
836 * Freeing a NULL pointer won't do
837 * anything. roxml_release also allow you to remove all
838 * previously allocated memory by using \ref RELEASE_ALL as argument.
839 * You can also safely use \ref RELEASE_LAST argument that will release the
840 * previously allocated varable within the current thread (making this
841 * function thread safe).
842 * if using roxml_release on a variable non roxml_mallocated, nothing will happen (ie variable won't be freed)
843 * \param data the pointer to delete or NULL or \ref RELEASE_ALL or \ref RELEASE_LAST
844 * \return void
845 */
846ROXML_API void roxml_release(void *data);
847
848/** \brief add a node to the tree
849 *
850 * \fn roxml_add_node(node_t *parent, int position, int type, char *name, char *value);
851 * this function add a new node to the tree. This will not update de buffer or file,
852 * only the RAM loaded tree. One should call \ref roxml_commit_changes to save modifications.
853 * If the parent node is an \ref ROXML_ELM_NODE, then, new node will be added as a child. Else
854 * the node will be added as a sibling of the parent node. In the later case, position parameter describes
855 * the position in the sibling list, instead of position in the children list.
856 * \param parent the parent node
857 * \param position the position as a child of parent 1 is the first child, 0 for auto position at the end of children list...
858 * \param type the type of node between \ref ROXML_ATTR_NODE, \ref ROXML_ELM_NODE, \ref ROXML_TXT_NODE, \ref ROXML_CDATA_NODE, \ref ROXML_PI_NODE, \ref ROXML_CMT_NODE, \ref ROXML_NSDEF_NODE, \ref ROXML_NS_NODE.
859 * \param name the name of the node (mandatory for \ref ROXML_ATTR_NODE and \ref ROXML_ELM_NODE and \ref ROXML_PI_NODE and \ref ROXML_NSDEF_NODE and \ref ROXML_NS_NODE only)
860 * \param value the text content (mandatory for \ref ROXML_TXT_NODE, \ref ROXML_CDATA_NODE, \ref ROXML_CMT_NODE, \ref ROXML_ATTR_NODE and \ref ROXML_NSDEF_NODE optional for \ref ROXML_ELM_NODE, \ref ROXML_PI_NODE). The text content for an attribute is the attribute value
861 * \return the newly created node
862 * \see roxml_commit_changes
863 * \see roxml_commit_buffer
864 * \see roxml_commit_file
865 * \see roxml_del_node
866 * \see roxml_close
867 *
868 * paramaters name and value depending on node type:
869 * - \ref ROXML_ELM_NODE take at least a node name. the parameter value is optional and represents the text content.
870 * - \ref ROXML_TXT_NODE ignore the node name. the parameter value represents the text content.
871 * - \ref ROXML_CDATA_NODE ignore the node name. the parameter value represents the text content that will be encapsulated in CDATA tags.
872 * - \ref ROXML_CMT_NODE ignore the node name. the parameter value represents the comment.
873 * - \ref ROXML_PI_NODE take the node name as process-instruction target. the parameter value represents the content of processing-instruction.
874 * - \ref ROXML_ATTR_NODE take an attribute name. and the attribute value as given by parameter value.
875 * - \ref ROXML_NSDEF_NODE take an attribute name (empty string for default namespace). and the namespace value as given by parameter value.
876 * - \ref ROXML_NS_NODE take an attribute name (empty string for default namespace).
877 *
878 * some examples to obtain this xml result file
879\verbatim
880<root>
881 <!-- sample XML file -->
882 <item id="42">
883 <price>
884 24
885 </price>
886 </item>
887</root>
888\endverbatim
889 *
890 * \code
891 * #include <roxml.h>
892 *
893 * int main(void)
894 * {
895 * node_t *root = roxml_add_node(NULL, 0, ROXML_ELM_NODE, "xml", NULL);
896 * node_t *tmp = roxml_add_node(root, 0, ROXML_CMT_NODE, NULL, "sample XML file");
897 * tmp = roxml_add_node(root, 0, ROXML_ELM_NODE, "item", NULL);
898 * roxml_add_node(tmp, 0, ROXML_ATTR_NODE, "id", "42");
899 * tmp = roxml_add_node(tmp, 0, ROXML_ELM_NODE, "price", "24");
900 * roxml_commit_changes(root, "/tmp/test.xml", NULL, 1);
901 * roxml_close(root);
902 * return 0;
903 * }
904 * \endcode
905 * Or also:
906 * \code
907 * #include <roxml.h>
908 *
909 * int main(void)
910 * {
911 * node_t *root = roxml_add_node(NULL, 0, ROXML_ELM_NODE, "xml", NULL);
912 * node_t *tmp = roxml_add_node(root, 0, ROXML_CMT_NODE, NULL, "sample XML file");
913 * tmp = roxml_add_node(root, 0, ROXML_ELM_NODE, "item", NULL);
914 * roxml_add_node(tmp, 0, ROXML_ATTR_NODE, "id", "42");
915 * tmp = roxml_add_node(tmp, 0, ROXML_ELM_NODE, "price", NULL);
916 * tmp = roxml_add_node(tmp, 0, ROXML_TXT_NODE, NULL, "24");
917 * roxml_commit_changes(root, "/tmp/test.xml", NULL, 1);
918 * roxml_close(root);
919 * return 0;
920 * }
921 * \endcode
922 *
923 * If you need a valid XML doc, just start by adding a corresponding process-instruction.
924 * Example, to obtain this xml file:
925 * \verbatim
926<?xml version="1.0" encoding="UTF-8"?>
927<!--sample file-->
928<doc>
929 basic content
930 <item/>
931 <item/>
932 <item/>
933</doc>
934\endverbatim
935 * \code
936 * #include <roxml.h>
937 *
938 * int main(void)
939 * {
940 * node_t *root = roxml_add_node(NULL, 0, ROXML_PI_NODE, "xml", "version=\"1.0\" encoding=\"UTF-8\"");
941 * node_t *node = roxml_add_node(root, 0, ROXML_CMT_NODE, NULL, "sample file");
942 * node = roxml_add_node(root, 0, ROXML_ELM_NODE, "doc", "basic content");
943 * roxml_add_node(node, 0, ROXML_ELM_NODE, "item", NULL);
944 * roxml_add_node(node, 0, ROXML_ELM_NODE, "item", NULL);
945 * roxml_add_node(node, 0, ROXML_ELM_NODE, "item", NULL);
946 * roxml_commit_changes(root, "/tmp/test.xml", NULL, 1);
947 * roxml_close(root);
948 * return 0;
949 * }
950 * \endcode
951 */
952ROXML_API node_t * roxml_add_node(node_t *parent, int position, int type, char *name, char *value);
953
954/** \brief text node getter function
955 *
956 * \fn roxml_get_txt(node_t *n, int nth);
957 * this function return the text content of a node as a \ref ROXML_TXT_NODE
958 * the content of the text node can be read using the roxml_get_content function
959 * \param n the node that contains text
960 * \param nth the nth text node to retrieve
961 * \return the text node or ROXML_INVALID_DOC (NULL)
962 * \see roxml_get_txt_nb
963 * \see roxml_get_nodes
964 * \see roxml_get_content
965 *
966 * example:
967 * given this xml file:
968 * \verbatim
969<xml>
970 This is
971 <item/>
972 an example
973 <item/>
974 of text nodes
975</xml>
976\endverbatim
977 * \code
978 * #include <stdio.h>
979 * #include <roxml.h>
980 *
981 * int main(void)
982 * {
983 * int len;
984 * node_t *root = roxml_load_doc("/tmp/doc.xml");
985 * node_t *item = roxml_get_chld(root, NULL, 0);
986 *
987 * node_t *text = roxml_get_txt(item, 0);
988 * char * text_content = roxml_get_content(text, NULL, 0, &len);
989 * // HERE text_content is equal to "This is"
990 * printf("text_content = '%s'\n", text_content);
991 *
992 * text = roxml_get_txt(item, 1);
993 * text_content = roxml_get_content(text, NULL, 0, &len);
994 * // HERE text_content is equal to "an example"
995 * printf("text_content = '%s'\n", text_content);
996 *
997 * text = roxml_get_txt(item, 2);
998 * text_content = roxml_get_content(text, NULL, 0, &len);
999 * // HERE text_content is equal to "of text nodes"
1000 * printf("text_content = '%s'\n", text_content);
1001 *
1002 * roxml_close(item);
1003 * return 0;
1004 * }
1005 * \endcode
1006 */
1007ROXML_API node_t * roxml_get_txt(node_t *n, int nth);
1008
1009/** \brief text node number getter function
1010 *
1011 * \fn roxml_get_txt_nb(node_t *n);
1012 * this function return the number of text nodes in
1013 * a standard node
1014 * \param n the node to search into
1015 * \return the number of text node
1016 * \see roxml_get_txt
1017 */
1018ROXML_API int roxml_get_txt_nb(node_t *n);
1019
1020/** \brief node deletion function
1021 *
1022 * \fn roxml_del_node(node_t *n);
1023 * this function delete a node from the tree. The node is not really deleted
1024 * from the file or buffer until the roxml_commit_changes is called, but it won't be
1025 * visible anymore in the XML tree.
1026 * \param n the node to delete
1027 * \return
1028 * \see roxml_add_node
1029 * \see roxml_commit_changes
1030 * \see roxml_commit_buffer
1031 * \see roxml_commit_file
1032 *
1033 * \warning when removing a nsdef node, all node using this namespace will be updated and inherit their parent namespace
1034 */
1035ROXML_API void roxml_del_node(node_t *n);
1036
1037/** \brief sync function
1038 *
1039 * \fn roxml_commit_changes(node_t *n, char * dest, char ** buffer, int human);
1040 * \deprecated
1041 * this function sync changes from the RAM tree to the given buffer or file in human or one-line format
1042 * The tree will be processed starting with the root node 'n' and following with all its children or if n is the root, all its siblings and children.
1043 * The tree will be dumped to a file if 'dest' is not null and contains a valid path.
1044 * The tree will be dumped to a buffer if 'buffer' is not null. the buffer is allocated by the library
1045 * and a pointer to it will be stored into 'buffer'. The allocated buffer can be freed usinf free()
1046 * \warning in the case of a tree loaded using roxml_load_doc, the roxml_commit_changes cannot be done to that same file
1047 * since it may override datas it need. This usually result in a new file filled with garbages. The solution is to write it to a temporary file and rename it after roxml_close the current tree.
1048 *
1049 * This function is now deprecated and one should use roxml_commit_buffer or roxml_commit_file that achieves the exact same goal.
1050 *
1051 * \param n the root node of the tree to write
1052 * \param dest the path to a file to write tree to
1053 * \param buffer the address of a buffer where the tree will be written. This buffer have to be freed after use
1054 * \param human 0 for one-line tree, or 1 for human format (using tabs, newlines...)
1055 * \return the number of bytes written to file or buffer
1056 * \see roxml_commit_buffer
1057 * \see roxml_commit_file
1058 *
1059 * This is a legacy function that proposes the same functionnalities as both
1060 * \c roxml_commit_file and \c roxml_commit_buffer. New code should use the
1061 * latter functions when needed.
1062 *
1063 * One should do:
1064 * \code
1065 * #include <roxml.h>
1066 *
1067 * int main(void)
1068 * {
1069 * node_t *root = roxml_add_node(NULL, 0, ROXML_ELM_NODE, "xml", NULL);
1070 * node_t *tmp = roxml_add_node(root, 0, ROXML_CMT_NODE, NULL, "sample XML file");
1071 * tmp = roxml_add_node(root, 0, ROXML_ELM_NODE, "item", NULL);
1072 * roxml_add_node(tmp, 0, ROXML_ATTR_NODE, "id", "42");
1073 * tmp = roxml_add_node(tmp, 0, ROXML_ELM_NODE, "price", "24");
1074 * roxml_commit_changes(root, "/tmp/test.xml", NULL, 1);
1075 * return 0;
1076 * }
1077 * \endcode
1078 * to generate the following xml bloc:
1079\verbatim
1080<root>
1081 <!-- sample XML file -->
1082 <item id="42">
1083 <price>
1084 24
1085 </price>
1086 </item>
1087</root>
1088\endverbatim
1089 * or also
1090 * \code
1091 * #include <roxml.h>
1092 *
1093 * int main(void)
1094 * {
1095 * node_t *root = roxml_add_node(NULL, 0, ROXML_ELM_NODE, "xml", NULL);
1096 * node_t *tmp = roxml_add_node(root, 0, ROXML_CMT_NODE, NULL, "sample XML file");
1097 * tmp = roxml_add_node(root, 0, ROXML_ELM_NODE, "item", NULL);
1098 * roxml_add_node(tmp, 0, ROXML_ATTR_NODE, "id", "42");
1099 * tmp = roxml_add_node(tmp, 0, ROXML_ELM_NODE, "price", "24");
1100 * roxml_commit_changes(root, "/tmp/test.xml", NULL, 0);
1101 * roxml_close(root);
1102 * return 0;
1103 * }
1104 * \endcode
1105 * to generate the following xml bloc:
1106\verbatim
1107<root><!-- sample XML file --><item id="42"><price>24</price></item></root>
1108\endverbatim
1109 * the buffer variant works more or less the same way
1110 * \code
1111 * #include <stdio.h>
1112 * #include <roxml.h>
1113 *
1114 * int main(void)
1115 * {
1116 * int len = 0;
1117 * char * buffer = NULL;
1118 * FILE * file_out;
1119 * node_t *root = roxml_add_node(NULL, 0, ROXML_ELM_NODE, "xml", NULL);
1120 * node_t *tmp = roxml_add_node(root, 0, ROXML_CMT_NODE, NULL, "sample XML file");
1121 * tmp = roxml_add_node(root, 0, ROXML_ELM_NODE, "item", NULL);
1122 * roxml_add_node(tmp, 0, ROXML_ATTR_NODE, "id", "42");
1123 * tmp = roxml_add_node(tmp, 0, ROXML_ELM_NODE, "price", "24");
1124 *
1125 * len = roxml_commit_changes(root, NULL, &buffer, 0);
1126 *
1127 * file_out = fopen("/tmp/test.xml", "w");
1128 * fwrite(buffer, 1, len, file_out);
1129 * fclose(file_out);
1130 *
1131 * roxml_close(root);
1132 * return 0;
1133 * }
1134 * \endcode
1135 * to generate the following xml bloc:
1136\verbatim
1137<root><!-- sample XML file --><item id="42"><price>24</price></item></root>
1138\endverbatim
1139 * \see roxml_commit_file
1140 * \see roxml_commit_buffer
1141 * \see roxml_commit_fd
1142 */
1143ROXML_API int roxml_commit_changes(node_t *n, char *buffer, int human);
1144
1145/** \brief sync to named file function
1146 *
1147 * \fn roxml_commit_file(node_t *n, char * dest, int human);
1148 * this function sync changes from the RAM tree to the given file in human or one-line format
1149 * The tree will be processed starting with the root node 'n' and following with all its children or if n is the root, all its siblings and children.
1150 * The tree will be dumped to a file if 'dest' is not null and contains a valid path.
1151 * \warning in the case of a tree loaded using roxml_load_doc, the roxml_commit_file cannot be done to that same file
1152 * since it may override datas it needs. This usually resultis in a new file filled with garbage. The solution is to write it to a temporary file and rename it after roxml_close the current tree.
1153 *
1154 * \param n the root node of the tree to write
1155 * \param dest the path to a file to write tree to
1156 * \param human 0 for one-line tree, or 1 for human format (using tabs, newlines...)
1157 * \return the number of bytes written to file or buffer
1158 *
1159 * One should do:
1160 * \code
1161 * #include <roxml.h>
1162 *
1163 * int main(void)
1164 * {
1165 * node_t *root = roxml_add_node(NULL, 0, ROXML_ELM_NODE, "xml", NULL);
1166 * node_t *tmp = roxml_add_node(root, 0, ROXML_CMT_NODE, NULL, "sample XML file");
1167 * tmp = roxml_add_node(root, 0, ROXML_ELM_NODE, "item", NULL);
1168 * roxml_add_node(tmp, 0, ROXML_ATTR_NODE, "id", "42");
1169 * tmp = roxml_add_node(tmp, 0, ROXML_ELM_NODE, "price", "24");
1170 * roxml_commit_file(root, "/tmp/test.xml", 1);
1171 * roxml_close(root);
1172 * return 0;
1173 * }
1174 * \endcode
1175 * to generate the following xml bloc:
1176\verbatim
1177<root>
1178 <!-- sample XML file -->
1179 <item id="42">
1180 <price>
1181 24
1182 </price>
1183 </item>
1184</root>
1185\endverbatim
1186 * or also
1187 * \code
1188 * #include <roxml.h>
1189 *
1190 * int main(void)
1191 * {
1192 * node_t *root = roxml_add_node(NULL, 0, ROXML_ELM_NODE, "xml", NULL);
1193 * node_t *tmp = roxml_add_node(root, 0, ROXML_CMT_NODE, NULL, "sample XML file");
1194 * tmp = roxml_add_node(root, 0, ROXML_ELM_NODE, "item", NULL);
1195 * roxml_add_node(tmp, 0, ROXML_ATTR_NODE, "id", "42");
1196 * tmp = roxml_add_node(tmp, 0, ROXML_ELM_NODE, "price", "24");
1197 * roxml_commit_file(root, "/tmp/test.xml", 0);
1198 * roxml_close(root);
1199 * return 0;
1200 * }
1201 * \endcode
1202 * to generate the following xml bloc:
1203\verbatim
1204<root><!-- sample XML file --><item id="42"><price>24</price></item></root>
1205\endverbatim
1206 * \see roxml_commit_changes
1207 * \see roxml_commit_buffer
1208 * \see roxml_commit_fd
1209 */
1210ROXML_API int roxml_commit_file(node_t *n, char *dest, int human);
1211
1212/** \brief sync to a memory buffer function
1213 *
1214 * \fn roxml_commit_buffer(node_t *n, char ** buffer, int human);
1215 * this function syncs changes from the RAM tree to the given buffer in human or one-line format
1216 * The tree will be processed starting with the root node 'n' and following with all its children or if n is the root, all its siblings and children.
1217 * The tree will be dumped to a buffer if 'buffer' is not null. the buffer is allocated by the library
1218 * and a pointer to it will be stored into 'buffer'. The allocated buffer can be freed using free()
1219 *
1220 * \param n the root node of the tree to write
1221 * \param buffer the address of a buffer where the tree will be written. This buffer have to be freed after use
1222 * \param human 0 for one-line tree, or 1 for human format (using indentation, newlines...)
1223 * \return the number of bytes written to file or buffer
1224 *
1225 * One should do:
1226 * \code
1227 * #include <roxml.h>
1228 *
1229 * int main(void)
1230 * {
1231 * char *buffer = NULL;
1232 * node_t *root = roxml_add_node(NULL, 0, ROXML_ELM_NODE, "xml", NULL);
1233 * node_t *tmp = roxml_add_node(root, 0, ROXML_CMT_NODE, NULL, "sample XML file");
1234 * tmp = roxml_add_node(root, 0, ROXML_ELM_NODE, "item", NULL);
1235 * roxml_add_node(tmp, 0, ROXML_ATTR_NODE, "id", "42");
1236 * tmp = roxml_add_node(tmp, 0, ROXML_ELM_NODE, "price", "24");
1237 * roxml_commit_changes(root, &buffer, 1);
1238 * roxml_close(root);
1239 * return 0;
1240 * }
1241 * \endcode
1242 * to generate the following xml bloc:
1243\verbatim
1244<root>
1245 <!-- sample XML file -->
1246 <item id="42">
1247 <price>
1248 24
1249 </price>
1250 </item>
1251</root>
1252\endverbatim
1253 * or also
1254 * \code
1255 * #include <roxml.h>
1256 *
1257 * int main(void)
1258 * {
1259 * char *buffer = NULL;
1260 * node_t *root = roxml_add_node(NULL, 0, ROXML_ELM_NODE, "xml", NULL);
1261 * node_t *tmp = roxml_add_node(root, 0, ROXML_CMT_NODE, NULL, "sample XML file");
1262 * tmp = roxml_add_node(root, 0, ROXML_ELM_NODE, "item", NULL);
1263 * roxml_add_node(tmp, 0, ROXML_ATTR_NODE, "id", "42");
1264 * tmp = roxml_add_node(tmp, 0, ROXML_ELM_NODE, "price", "24");
1265 * roxml_commit_buffer(root, &buffer, 0);
1266 * roxml_close(root);
1267 * return 0;
1268 * }
1269 * \endcode
1270 * to generate the following xml bloc:
1271\verbatim
1272<root><!-- sample XML file --><item id="42"><price>24</price></item></root>
1273\endverbatim
1274 * \see roxml_commit_changes
1275 * \see roxml_commit_file
1276 * \see roxml_commit_fd
1277 */
1278ROXML_API int roxml_commit_buffer(node_t *n, char **buffer, int human);
1279
1280/** \brief sync to file descriptor function
1281 *
1282 * \fn roxml_commit_fd(node_t *n, int fd, int human);
1283 * this function synchronizes changes from the RAM tree to the given file in human or one-line format.
1284 * The tree will be processed starting with the root node 'n' and following with all its children or if n is the root, all its siblings and children.
1285 * The tree will be dumped to a file if fd is a valid file descriptor.
1286 * \warning in the case of a tree loaded using roxml_load_doc, the roxml_commit_fd cannot be done to that same file
1287 * since it may override datas it needs. This usually results in a new file filled with garbage. The solution is to write it to a temporary file and rename it after roxml_close the current tree.
1288 *
1289 * \param n the root node of the tree to write
1290 * \param fd the file descriptor to write tree to
1291 * \param human 0 for one-line tree, or 1 for human format (using tabs, newlines...)
1292 * \return the number of bytes written to file
1293 *
1294 * The file described by fd is not truncated so this function allows one to append an XML subtree to an existing file.
1295 *
1296 * One should do:
1297 * \code
1298 * #include <roxml.h>
1299 *
1300 * int main(void)
1301 * {
1302 * int fd = open("/tmp/test.xml", O_TRUNC|O_WRONLY, 0666);
1303 * node_t *root = roxml_add_node(NULL, 0, ROXML_ELM_NODE, "xml", NULL);
1304 * node_t *tmp = roxml_add_node(root, 0, ROXML_CMT_NODE, NULL, "sample XML file");
1305 * tmp = roxml_add_node(root, 0, ROXML_ELM_NODE, "item", NULL);
1306 * roxml_add_node(tmp, 0, ROXML_ATTR_NODE, "id", "42");
1307 * tmp = roxml_add_node(tmp, 0, ROXML_ELM_NODE, "price", "24");
1308 * roxml_commit_fd(root, fd, 1);
1309 * roxml_close(root);
1310 * close(fd);
1311 * return 0;
1312 * }
1313 * \endcode
1314 * to generate the following xml bloc:
1315\verbatim
1316<root>
1317 <!-- sample XML file -->
1318 <item id="42">
1319 <price>
1320 24
1321 </price>
1322 </item>
1323</root>
1324\endverbatim
1325 * or also
1326 * \code
1327 * #include <roxml.h>
1328 *
1329 * int main(void)
1330 * {
1331 * int fd = open("/tmp/test.xml", O_TRUNC|O_WRONLY, 0666);
1332 * node_t *root = roxml_add_node(NULL, 0, ROXML_ELM_NODE, "xml", NULL);
1333 * node_t *tmp = roxml_add_node(root, 0, ROXML_CMT_NODE, NULL, "sample XML file");
1334 * tmp = roxml_add_node(root, 0, ROXML_ELM_NODE, "item", NULL);
1335 * roxml_add_node(tmp, 0, ROXML_ATTR_NODE, "id", "42");
1336 * tmp = roxml_add_node(tmp, 0, ROXML_ELM_NODE, "price", "24");
1337 * roxml_commit_fd(root, fd, 0);
1338 * roxml_close(root);
1339 * close(fd);
1340 * return 0;
1341 * }
1342 * \endcode
1343 * to generate the following xml bloc:
1344\verbatim
1345<root><!-- sample XML file --><item id="42"><price>24</price></item></root>
1346\endverbatim
1347 * \see roxml_commit_changes
1348 * \see roxml_commit_file
1349 * \see roxml_commit_buffer
1350 */
1351ROXML_API int roxml_commit_fd(node_t *n, int fd, int human);
1352
1353char *roxml_process_special_characters(char *input);
1354
1355void roxml_init();
1356void roxml_clean_buffer();
1357
1358ROXML_API char *roxml_get_ns_name(node_t *n, char *buffer, int bufsize);
1359ROXML_API char *roxml_get_ns_content(node_t *n, char *buffer, int bufsize, int *size);
1360ROXML_API char *roxml_get_node_name(node_t *n, char *buffer, int bufsize);
1361
1362#ifdef __cplusplus
1363}
1364#endif
1365
1366#endif /* ROXML_H */