| /** \file roxml.h |
| * \brief header for libroxml.so |
| * |
| * This is the header file used to develop some |
| * software using the libroxml.so library. |
| * \author blunderer <blunderer@blunderer.org> |
| * \date 23 Dec 2008 |
| * |
| * Copyright (C) 2009 blunderer |
| * |
| * As a special exception to the LGPL v2.1 (below), the copyright holders of |
| * this library give you permission to statically link this library |
| * with independent modules to produce an executable, regardless of the license |
| * terms of these independent modules, and to copy and distribute the resulting |
| * executable under terms of your choice, provided that you also meet, for each |
| * linked independent module, the terms and conditions of the license of that |
| * module. The resulting executable may therefore be distributed without complying |
| * with the LGPL terms that state that recipients of your executable must be able |
| * to relink against modified versions of the library. |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * The author added a static linking exception, see License.txt. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| */ |
| |
| /******************************************************************************* |
| * ========================================================================== |
| * $Log$ |
| * |
| * 01 28 2019 cs.huang |
| * [MOLY00381872] [VMOLY] XCAP merge from UMOLYE |
| * XCAP sync from UMOLYE (OA part) |
| * |
| * 12 28 2018 howen.pu |
| * [MOLY00374881] Gen95 XCAP - USIR |
| * Gen 95 USIR - For XCAP. |
| * |
| * 12 28 2018 howen.pu |
| * [MOLY00374881] Gen95 XCAP - USIR |
| * |
| * Gen 95 USIR - For XCAP. |
| * |
| * |
| ****************************************************************************/ |
| |
| #ifndef ROXML_H |
| #define ROXML_H |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| /** |
| * \def ROXML_API |
| * |
| * part of the public API |
| */ |
| #define ROXML_API |
| |
| #ifndef ROXML_INT |
| /** \typedef node_t |
| * |
| * \brief node_t structure |
| * |
| * This is the structure for a node. This struct is very |
| * little as it only contains offset for node in file and |
| * tree links |
| */ |
| typedef struct node node_t; |
| #endif |
| |
| /** |
| * \def ROXML_INVALID_NODE |
| * |
| * constant for invalid nodes |
| */ |
| #define ROXML_INVALID_NODE 0x000 |
| |
| /** |
| * \def ROXML_ATTR_NODE |
| * |
| * constant for attribute nodes |
| * \see roxml_add_node |
| */ |
| #define ROXML_ATTR_NODE 0x008 |
| |
| /** |
| * \def ROXML_STD_NODE |
| * |
| * \deprecated |
| * constant for standard nodes |
| * |
| * \see roxml_add_node |
| * |
| */ |
| #define ROXML_STD_NODE 0x010 |
| |
| /** |
| * \def ROXML_ELM_NODE |
| * |
| * constant for element nodes |
| * \see roxml_add_node |
| */ |
| #define ROXML_ELM_NODE 0x010 |
| |
| /** |
| * \def ROXML_TXT_NODE |
| * |
| * constant for text nodes |
| * \see roxml_add_node |
| */ |
| #define ROXML_TXT_NODE 0x020 |
| |
| /** |
| * \def ROXML_CMT_NODE |
| * |
| * constant for comment nodes |
| * \see roxml_add_node |
| */ |
| #define ROXML_CMT_NODE 0x040 |
| |
| /** |
| * \def ROXML_PI_NODE |
| * |
| * constant for processing_intruction nodes |
| * \see roxml_add_node |
| */ |
| #define ROXML_PI_NODE 0x080 |
| |
| /** |
| * \def ROXML_NS_NODE |
| * |
| * constant for namespace nodes |
| * \see roxml_add_node |
| */ |
| #define ROXML_NS_NODE 0x100 |
| |
| /** |
| * \def ROXML_NSDEF_NODE |
| * |
| * constant for namespace definition nodes |
| * \see roxml_add_node |
| */ |
| #define ROXML_NSDEF_NODE (ROXML_NS_NODE | ROXML_ATTR_NODE) |
| |
| /** |
| * \def ROXML_CDATA_NODE |
| * |
| * constant for cdata nodes |
| * \see roxml_add_node |
| */ |
| #define ROXML_CDATA_NODE (ROXML_TXT_NODE | 0x200) |
| |
| /** |
| * \def ROXML_DOCTYPE_NODE |
| * |
| * constant for doctype nodes |
| * \see roxml_add_node |
| */ |
| #define ROXML_DOCTYPE_NODE 0x400 |
| |
| /** |
| * \def ROXML_ALL_NODES |
| * |
| * constant for all types of nodes |
| * \see roxml_add_node |
| */ |
| #define ROXML_ALL_NODES (ROXML_PI_NODE | ROXML_CMT_NODE | ROXML_TXT_NODE | ROXML_ATTR_NODE | ROXML_ELM_NODE) |
| |
| /** |
| * \def ROXML_ALL_NODE |
| * |
| * constant for all types of nodes for backward compatibility |
| * \see roxml_add_node |
| */ |
| #define ROXML_ALL_NODE ROXML_ALL_NODES |
| |
| /** |
| * \def ROXML_NODE_TYPES |
| * |
| * constant for all nodes types |
| * \see roxml_get_types |
| */ |
| #define ROXML_NODE_TYPES 0x05f8 |
| |
| /** |
| * \def RELEASE_ALL |
| * |
| * when used with roxml_release, release all memory allocated by current thread |
| * \see roxml_release |
| */ |
| #define RELEASE_ALL (void*)-1 |
| |
| /** |
| * \def RELEASE_LAST |
| * |
| * when used with roxml_release, release last variable allocated |
| * \see roxml_release |
| * |
| * example: |
| * \code |
| * #include <stdio.h> |
| * #include <roxml.h> |
| * int main(void) |
| * { |
| * int len; |
| * node_t *root = roxml_load_doc("/tmp/doc.xml"); |
| * |
| * // roxml_get_content allocate a buffer and store the content in it if no buffer was given |
| * printf("root content = '%s'\n", roxml_get_content(root, NULL, 0, &len)); |
| * |
| * // release the last allocated buffer even if no pointer is maintained by the user |
| * roxml_release(RELEASE_LAST); |
| * |
| * // here no memory leak can occur. |
| * |
| * roxml_close(root); |
| * return 0; |
| * } |
| * \endcode |
| */ |
| #define RELEASE_LAST (void*)-2 |
| |
| /** |
| * \def ROXML_INVALID_DOC |
| * |
| * constant for invalid documents |
| */ |
| #define ROXML_INVALID_DOC (node_t*)0 |
| |
| /** \brief load function for buffers |
| * |
| * \fn node_t* roxml_load_buf(char *buffer); |
| * This function load a document by parsing all the corresponding nodes. |
| * The document must be contained inside the char * buffer given in parameter |
| * and remain valid until the roxml_close() function is called |
| * \param buffer the XML buffer to load |
| * \return the root node or ROXML_INVALID_DOC (NULL). errno is set to EINVAL in case of parsing error |
| * \see roxml_close |
| * \see roxml_load_fd |
| * \see roxml_load_doc |
| */ |
| ROXML_API node_t * roxml_load_buf(char *buffer); |
| |
| /** \brief load function for files |
| * |
| * \fn node_t* roxml_load_doc(char *filename); |
| * This function load a file document by parsing all the corresponding nodes |
| * \warning the file is not fully copied and thus, it should stay untouched until roxml_close is called on the corresponding XML tree. |
| * \param filename the XML document to load |
| * \return the root node or ROXML_INVALID_DOC (NULL). errno is set to EINVAL in case of parsing error |
| * \see roxml_close |
| * \see roxml_load_fd |
| * \see roxml_load_buf |
| */ |
| ROXML_API node_t * roxml_load_doc(char *filename); |
| |
| /** \brief load function for file descriptors |
| * |
| * \fn node_t* roxml_load_fd(int fd); |
| * This function load a document by parsing all the corresponding nodes |
| * \param fd the opened file descriptor to XML document to load |
| * \return the root node or ROXML_INVALID_DOC (NULL). errno is set to EINVAL in case of parsing error |
| * \see roxml_close |
| * \see roxml_load_doc |
| * \see roxml_load_buf |
| */ |
| ROXML_API node_t * roxml_load_fd(int fd); |
| |
| /** \brief unload function |
| * |
| * \fn void roxml_close(node_t *n); |
| * This function clear a document and all the corresponding nodes |
| * It release all memory allocated during roxml_load_doc or roxml_load_file or roxml_add_node. |
| * All nodes from the tree are not available anymore. |
| * \param n is any node of the tree to be cleaned |
| * \return void |
| * \see roxml_load_doc |
| * \see roxml_load_buf |
| * \see roxml_add_node |
| */ |
| ROXML_API void roxml_close(node_t *n); |
| |
| /** \brief next sibling getter function |
| * |
| * \fn node_t* roxml_get_next_sibling(node_t *n); |
| * This function returns the next sibling of a given node |
| * \param n is one node of the tree |
| * \return the next sibling node |
| */ |
| ROXML_API node_t * roxml_get_next_sibling(node_t *n); |
| |
| /** \brief prev sibling getter function |
| * |
| * \fn node_t* roxml_get_prev_sibling(node_t *n); |
| * This function returns the prev sibling of a given node |
| * \param n is one node of the tree |
| * \return the prev sibling node |
| */ |
| ROXML_API node_t * roxml_get_prev_sibling(node_t *n); |
| |
| /** \brief parent getter function |
| * |
| * \fn node_t* roxml_get_parent(node_t *n); |
| * This function returns the parent of a given node |
| * \param n is one node of the tree |
| * \return the parent node |
| */ |
| ROXML_API node_t * roxml_get_parent(node_t *n); |
| |
| /** \brief root getter function |
| * |
| * \fn node_t* roxml_get_root(node_t *n); |
| * This function returns the root of a tree containing the given node |
| * The root is defined as a virtual node that contains all first rank nodes if document is |
| * not a valid xml document: |
| * \verbatim |
| <data1> |
| <item/> |
| <item/> |
| </data1> |
| <data2> |
| <item/> |
| <item/> |
| </data2> |
| \endverbatim |
| * will be processed successfully and the root node will have 2 children: data1 and data2 |
| * |
| * if document was: |
| * \verbatim |
| <?xml version="1.0"> |
| <doc> |
| <data1> |
| <item/> |
| <item/> |
| </data1> |
| <data2> |
| <item/> |
| <item/> |
| </data2> |
| </doc> |
| \endverbatim |
| * In this case, the node "doc" will be the root, and will contain 2 children: data1 and data2 |
| * |
| * For a document to be valid, following conditions must be met: |
| * <ul> |
| * <li>the first node is a processing instruction with the string "xml" as target application.</li> |
| * <li>there is only one ELM node containing all document (but there may be several process-instructions or comments)</li> |
| * </ul> |
| * \param n is one node of the tree |
| * \return the root node |
| */ |
| ROXML_API node_t * roxml_get_root(node_t *n); |
| |
| /** \brief namespace getter function |
| * |
| * \fn node_t* roxml_get_ns(node_t *n); |
| * This function returns the namespace of a node |
| * |
| * \param n is one node of the tree |
| * \return the namespace or NULL if none are set for this node |
| * \see roxml_add_node |
| * \see roxml_set_ns |
| * \see roxml_get_nodes |
| * |
| * example: |
| * given the following xml file |
| * \verbatim |
| <xml xmlns:test="http://www.test.org"> |
| <test:item1 test:value1="3"/> |
| </xml> |
| \endverbatim |
| * \code |
| * #include <stdio.h> |
| * #include <roxml.h> |
| * |
| * int main(void) |
| * { |
| * node_t *root = roxml_load_doc("/tmp/doc.xml"); |
| * node_t *xml = roxml_get_chld(root, NULL, 0); |
| * node_t *nsdef = roxml_get_attr(xml, NULL, 0); |
| * node_t *node1 = roxml_get_chld(xml, NULL, 0); |
| * node_t *attr1 = roxml_get_attr(node1, NULL, 0); |
| * node_t *node1_ns = roxml_get_ns(node1); |
| * node_t *attr1_ns = roxml_get_ns(attr1); |
| * |
| * // here node1_ns and attr1_ns are the "test:" namespace |
| * if(node1_ns == nsdef) { |
| * printf("got the correct namespace node for elem\n"); |
| * } |
| * if(attr1_ns == nsdef) { |
| * printf("got the correct namespace node for attr\n"); |
| * } |
| * if(strcmp(roxml_get_name(node1_ns, NULL, 0), "test") == 0) { |
| * printf("got the correct namespace alias\n"); |
| * } |
| * if(strcmp(roxml_get_content(node1_ns, NULL, 0, NULL), "http://www.test.org") == 0) { |
| * printf("got the correct namespace\n"); |
| * } |
| * |
| * roxml_close(root); |
| * return 0; |
| * } |
| * |
| * \endcode |
| */ |
| ROXML_API node_t * roxml_get_ns(node_t *n); |
| |
| /** \brief namespace setter function |
| * |
| * \fn node_t* roxml_set_ns(node_t *n, node_t *ns); |
| * This function set the namespace of a node to the given namespace definition. |
| * The namespace must be previously defined in the xml tree in an ancestor of node n. |
| * |
| * \param n is one node of the tree |
| * \param ns is one nsdef node of the tree |
| * \return the node or ROXML_INVALID_DOC (NULL) if ns cannot be set |
| * \see roxml_add_node |
| * \see roxml_get_ns |
| * \see roxml_get_nodes |
| * |
| * \warning: Setting a namespace to a node is recursif: |
| * - it will update all element and attribute that are descendant from current node |
| * - namespace will be applied to all new node added as descendant as current node |
| */ |
| ROXML_API node_t * roxml_set_ns(node_t *n, node_t * ns); |
| |
| /** \brief comment getter function |
| * |
| * \fn node_t* roxml_get_cmt(node_t *n, int nth); |
| * This function returns the nth comment of a node |
| * |
| * \param n is one node of the tree |
| * \param nth is the id of the cmt to get |
| * \return the comment corresponding to id |
| * \see roxml_get_cmt_nb |
| * \see roxml_get_nodes |
| * |
| * example: |
| * given the following xml file |
| * \verbatim |
| <xml> |
| <item1/> |
| <!--comment1--> |
| <!--comment2--> |
| <item2/> |
| <item3/> |
| </xml> |
| \endverbatim |
| * \code |
| * #include <stdio.h> |
| * #include <roxml.h> |
| * |
| * int main(void) |
| * { |
| * node_t *root = roxml_load_doc("/tmp/doc.xml"); |
| * node_t *xml = roxml_get_chld(root, NULL, 0); |
| * node_t *cmt1 = roxml_get_cmt(xml, 0); |
| * node_t *cmt2 = roxml_get_cmt(xml, 1); |
| * |
| * // here cmt1 is the "comment1" node |
| * if(strcmp(roxml_get_content(cmt1, NULL, 0, NULL), "comment1") == 0) { |
| * printf("got the first comment\n"); |
| * } |
| * // and cmt2 is the "comment2" node |
| * if(strcmp(roxml_get_content(cmt2, NULL, 0, NULL), "comment2") == 0) { |
| * printf("got the second comment\n"); |
| * } |
| * |
| * roxml_close(root); |
| * return 0; |
| * } |
| * |
| * \endcode |
| */ |
| ROXML_API node_t * roxml_get_cmt(node_t *n, int nth); |
| |
| /** \brief comments number getter function |
| * |
| * \fn int roxml_get_cmt_nb(node_t *n); |
| * This function return the number of comments for a given node |
| * \param n is one node of the tree |
| * \return the number of comments |
| * \see roxml_get_cmt_nb |
| * \see roxml_get_nodes |
| */ |
| ROXML_API int roxml_get_cmt_nb(node_t *n); |
| |
| /** \brief chld getter function |
| * |
| * \fn node_t* roxml_get_chld(node_t *n, char * name, int nth); |
| * This function returns a given chld of a node etheir by name, or the nth child. |
| * |
| * \param n is one node of the tree |
| * \param name is the name of the child to get |
| * \param nth is the id of the chld to get |
| * \return the chld corresponding to name or id (if both are set, name is used) |
| * \see roxml_get_chld_nb |
| * |
| * example: |
| * given the following xml file |
| * \verbatim |
| <xml> |
| <item1/> |
| <item2/> |
| <item3/> |
| </xml> |
| \endverbatim |
| * \code |
| * #include <stdio.h> |
| * #include <roxml.h> |
| * |
| * int main(void) |
| * { |
| * node_t *root = roxml_load_doc("/tmp/doc.xml"); |
| * |
| * node_t *child_by_name = roxml_get_chld(root, "item2", 0); |
| * node_t *child_by_nth = roxml_get_chld(root, NULL, 2); |
| * |
| * // here child_by_name == child_by_nth |
| * if(child_by_name == child_by_nth) { |
| * printf("Nodes are equal\n"); |
| * } |
| * |
| * roxml_close(root); |
| * return 0; |
| * } |
| * \endcode |
| */ |
| ROXML_API node_t * roxml_get_chld(node_t *n, char *name, int nth); |
| |
| /** \brief chlds number getter function |
| * |
| * \fn int roxml_get_chld_nb(node_t *n); |
| * This function return the number of chlidren for a given node |
| * \param n is one node of the tree |
| * \return the number of chlildren |
| */ |
| ROXML_API int roxml_get_chld_nb(node_t *n); |
| |
| /** \brief process-instruction getter function |
| * |
| * \fn node_t* roxml_get_pi(node_t *n, int nth); |
| * This function returns the nth process-instruction of a node. |
| * |
| * \param n is one node of the tree |
| * \param nth is the id of the pi to get |
| * \return the process-instruction corresponding to id |
| * \see roxml_get_pi_nb |
| * \see roxml_get_nodes |
| * |
| * example: |
| * given the following xml file |
| * \verbatim |
| <xml> |
| <item1/> |
| <?test value="2"?> |
| <?test param="3"?> |
| <item2/> |
| <item3/> |
| </xml> |
| \endverbatim |
| * \code |
| * #include <stdio.h> |
| * #include <roxml.h> |
| * |
| * int main(void) |
| * { |
| * node_t *root = roxml_load_doc("/tmp/doc.xml"); |
| * node_t *xml = roxml_get_chld(root, NULL, 0); |
| * node_t *pi1 = roxml_get_pi(xml, 0); |
| * node_t *pi2 = roxml_get_pi(xml, 1); |
| * |
| * // here pi1 is the <?value="2"?> node |
| * if(strcmp(roxml_get_content(pi1, NULL, 0, NULL), "value=\"2\"") == 0) { |
| * printf("got the first process-instruction\n"); |
| * } |
| * // and pi2 is the <?param="3"?> node |
| * if(strcmp(roxml_get_content(pi2, NULL, 0, NULL), "param=\"3\"") == 0) { |
| * printf("got the second process-instruction\n"); |
| * } |
| * |
| * roxml_close(root); |
| * return 0; |
| * } |
| * |
| * \endcode |
| */ |
| ROXML_API node_t * roxml_get_pi(node_t *n, int nth); |
| |
| /** \brief process-instruction number getter function |
| * |
| * \fn int roxml_get_pi_nb(node_t *n); |
| * This function return the number of process-instruction in a given node |
| * \param n is one node of the tree |
| * \return the number of process-instructions |
| * \see roxml_get_pi |
| * \see roxml_get_nodes_nb |
| */ |
| ROXML_API int roxml_get_pi_nb(node_t *n); |
| |
| /** \brief name getter function |
| * |
| * \fn char* roxml_get_name(node_t *n, char * buffer, int size); |
| * This function return the name of the node or fill the current buffer with it if not NULL. |
| * if name is NULL, the function will allocate a buffer that user should free using |
| * roxml_release when no longer needed. |
| * depending on node type it will return: |
| * <ul> |
| * <li> ROXML_ELM_NODE: returns the node name</li> |
| * <li> ROXML_ATTR_NODE: returns the attribute name</li> |
| * <li> ROXML_PI_NODE: returns the process-instruction targeted application</li> |
| * <li> ROXML_TXT_NODE: returns NULL (or empty string if you provided a buffer in buffer param)</li> |
| * <li> ROXML_CMT_NODE: returns NULL (or empty string if you provided a buffer in buffer param)</li> |
| * <li> ROXML_NS_NODE: returns the namespace alias associated with the ns node </li> |
| * </ul> |
| * Be carreful as if your buffer is too short for the returned string, it will be truncated |
| * \param n is one node of the tree |
| * \param buffer a buffer pointer or NULL if has to be auto allocated |
| * \param size the size of buffer pointed by buffer if not NULL |
| * \return the name of the node (return our buffer pointer if it wasn't NULL) |
| * \see roxml_release |
| */ |
| ROXML_API char * roxml_get_name(node_t *n, char *buffer, int size); |
| |
| /** \brief content getter function |
| * |
| * \fn char * roxml_get_content(node_t *n, char * buffer, int bufsize, int * size); |
| * |
| * This function returns the content of a node.; |
| * if the returned pointer is NULL then the node either has no content or this function is irrelevant for this kind of node. |
| * depending on node type it will return: |
| * <ul> |
| * <li> ROXML_ELM_NODE: returns the concatenation of all direct text node children</li> |
| * <li> ROXML_ATTR_NODE: returns the attribute value</li> |
| * <li> ROXML_PI_NODE: returns the process-instruction instruction</li> |
| * <li> ROXML_TXT_NODE: returns the text content of the node</li> |
| * <li> ROXML_CMT_NODE: returns the text content of the comment</li> |
| * <li> ROXML_NS_NODE: returns the namespace definition (usually an URL)</li> |
| * </ul> |
| * returned string should be freed using roxml_release when not used anymore |
| * \param n is one node of the tree |
| * \param buffer is the buffer where result will be written or NULL for internal allocation |
| * \param bufsize the size if using custom buffer |
| * \param size the actual size of copied result. returned size should be less that buffer size since roxml_get_content |
| * will add the \0. if buffer was not NULL and size == buf_size, then given buffer was too small and node content was truncated |
| * \return the text content |
| * \see roxml_release |
| */ |
| ROXML_API char * roxml_get_content(node_t *n, char *buffer, int bufsize, int *size); |
| |
| /** \brief number of nodes getter function |
| * |
| * \fn int roxml_get_nodes_nb(node_t *n, int type); |
| * |
| * This function returns the number of nodes matching type flag contained in a given node |
| * all other roxml_get_*_nb are wrapper to this |
| * \param n is one node of the tree |
| * \param type is the bitmask of node types we want to consider |
| * \return the number of nodes |
| * \see roxml_get_attr_nb |
| * \see roxml_get_chld_nb |
| * \see roxml_get_txt_nb |
| * \see roxml_get_cmt_nb |
| * \see roxml_get_pi_nb |
| * |
| * example: |
| * given the following xml file |
| * \verbatim |
| <xml> |
| <!-- comment --> |
| <?value="2"?> |
| <product id="42" class="item"/> |
| <product id="43" class="item"/> |
| </xml> |
| \endverbatim |
| * \code |
| * #include <stdio.h> |
| * #include <roxml.h> |
| * |
| * int main(void) |
| * { |
| * node_t *root = roxml_load_doc("/tmp/doc.xml"); |
| * |
| * int all_nodes_1 = roxml_get_nodes_nb(root, ROXML_ELM_NODE | ROXML_CMT_NODE | ROXML_PI_NODE | ROXML_TXT_NODE | ROXML_ATTR_NODE); |
| * int all_nodes_2 = roxml_get_nodes_nb(root, ROXML_ALL_NODES); |
| * |
| * // here all_nodes_1 == all_nodes_2 |
| * if(all_nodes_1 == all_nodes_2) { |
| * printf("%d Nodes are contained in root\n", all_nodes_1); |
| * } |
| * |
| * // let's count elm node (== children) |
| * int elm_nodes1 = roxml_get_nodes_nb(root, ROXML_ELM_NODE); |
| * int elm_nodes2 = roxml_get_chld_nb(root); |
| * // here elm_nodes1 == elm_nodes2 == 2 |
| * if(elm_nodes1 == elm_nodes2) { |
| * printf("%d ELM Nodes are contained in root\n", elm_nodes_1); |
| * } |
| * |
| * // we can also count all node except elm nodes, doing: |
| * int almost_all_nodes = roxml_get_nodes_nb(root, ROXML_ALL_NODES & ~ROXML_ELM_NODE); |
| * // here almost_all_nodes = 2 since we have one comment node and one processing-instruction node |
| * if(almost_all_nodes == 2) { |
| * printf("%d non ELM Nodes are contained in root\n", almost_all_nodes_1); |
| * } |
| * |
| * roxml_close(root); |
| * return 0; |
| * } |
| * \endcode |
| */ |
| ROXML_API int roxml_get_nodes_nb(node_t *n, int type); |
| |
| /** \brief nodes getter function |
| * |
| * \fn char* roxml_get_nodes(node_t *n, int type, char * name, int nth); |
| * This function get the nth node matching type contained in a node, or the first node named name. |
| * All other roxml_get_* are wrapper to this function. |
| * When asking for several node type (let say ROXML_ALL_NODES), all ROXML_ATTR_NODE will be |
| * placed first, then, all other nodes will come mixed, depending on xml document order. |
| * |
| * \param n is one node of the tree |
| * \param type is the bitmask of node types we want to consider |
| * \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 |
| * \param nth the id of attribute to read |
| * \return the node corresponding to name or id (if both are set, name is used) |
| * \see roxml_get_attr |
| * \see roxml_get_chld |
| * \see roxml_get_txt |
| * \see roxml_get_cmt |
| * \see roxml_get_pi |
| */ |
| ROXML_API node_t * roxml_get_nodes(node_t *n, int type, char *name, int nth); |
| |
| /** \brief number of attribute getter function |
| * |
| * \fn int roxml_get_attr_nb(node_t *n); |
| * |
| * This function returns the number of attributes for a given node |
| * \param n is one node of the tree |
| * \return the number of attributes in node |
| */ |
| ROXML_API int roxml_get_attr_nb(node_t *n); |
| |
| /** \brief attribute getter function |
| * |
| * \fn node_t* roxml_get_attr(node_t *n, char * name, int nth); |
| * This function get the nth attribute of a node. |
| * \param n is one node of the tree |
| * \param name is the name of the attribute to get |
| * \param nth the id of attribute to read |
| * \return the attribute corresponding to name or id (if both are set, name is used) |
| * |
| * example: |
| * given the following xml file |
| * \verbatim |
| <xml> |
| <product id="42" class="item"/> |
| </xml> |
| \endverbatim |
| * \code |
| * #include <stdio.h> |
| * #include <roxml.h> |
| * |
| * int main(void) |
| * { |
| * node_t *root = roxml_load_doc("/tmp/doc.xml"); |
| * node_t *item1 = roxml_get_chld(root, NULL, 0); |
| * node_t *item2 = roxml_get_chld(item1, NULL, 0); |
| * |
| * node_t *attr_by_name = roxml_get_attr(item2, "id", 0); |
| * node_t *attr_by_nth = roxml_get_attr(item2, NULL, 0); |
| * |
| * // here attr_by_name == attr_by_nth |
| * if(attr_by_name == attr_by_nth) { |
| * printf("Nodes are equal\n"); |
| * } |
| * |
| * roxml_close(root); |
| * return 0; |
| * } |
| * \endcode |
| */ |
| ROXML_API node_t * roxml_get_attr(node_t *n, char *name, int nth); |
| |
| /** \brief exec path function |
| * |
| * \fn roxml_xpath(node_t *n, char * path, int *nb_ans); |
| * This function return a node set (table of nodes) corresponding to a given xpath. |
| * resulting node set should be roxml_release when not used anymore (but not individual nodes) |
| * \param n is one node of the tree |
| * \param path the xpath to use |
| * \param nb_ans the number of results |
| * \return the node table or NULL |
| * |
| * handled xpath are described in \ref xpath |
| */ |
| ROXML_API node_t ** roxml_xpath(node_t *n, char *path, int *nb_ans); |
| |
| /** \brief node type function |
| * |
| * \fn roxml_get_type(node_t *n); |
| * 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. |
| * Warning: ROXML_CDATA_NODE are special. They return a type as ROXML_TXT_NODE. |
| * \param n is the node to test |
| * \return the node type |
| */ |
| ROXML_API int roxml_get_type(node_t *n); |
| |
| /** \brief node get position function |
| * |
| * \fn roxml_get_node_position(node_t *n); |
| * This function tells the index of a node between all its siblings homonyns. |
| * \param n is the node to test |
| * \return the postion between 1 and N |
| */ |
| ROXML_API int roxml_get_node_position(node_t *n); |
| |
| /** \brief memory cleanning function |
| * |
| * \fn roxml_release(void * data); |
| * This function release the memory pointed by pointer |
| * just like free would but for memory allocated with roxml_malloc. |
| * Freeing a NULL pointer won't do |
| * anything. roxml_release also allow you to remove all |
| * previously allocated memory by using \ref RELEASE_ALL as argument. |
| * You can also safely use \ref RELEASE_LAST argument that will release the |
| * previously allocated varable within the current thread (making this |
| * function thread safe). |
| * if using roxml_release on a variable non roxml_mallocated, nothing will happen (ie variable won't be freed) |
| * \param data the pointer to delete or NULL or \ref RELEASE_ALL or \ref RELEASE_LAST |
| * \return void |
| */ |
| ROXML_API void roxml_release(void *data); |
| |
| /** \brief add a node to the tree |
| * |
| * \fn roxml_add_node(node_t *parent, int position, int type, char *name, char *value); |
| * this function add a new node to the tree. This will not update de buffer or file, |
| * only the RAM loaded tree. One should call \ref roxml_commit_changes to save modifications. |
| * If the parent node is an \ref ROXML_ELM_NODE, then, new node will be added as a child. Else |
| * the node will be added as a sibling of the parent node. In the later case, position parameter describes |
| * the position in the sibling list, instead of position in the children list. |
| * \param parent the parent node |
| * \param position the position as a child of parent 1 is the first child, 0 for auto position at the end of children list... |
| * \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. |
| * \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) |
| * \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 |
| * \return the newly created node |
| * \see roxml_commit_changes |
| * \see roxml_commit_buffer |
| * \see roxml_commit_file |
| * \see roxml_del_node |
| * \see roxml_close |
| * |
| * paramaters name and value depending on node type: |
| * - \ref ROXML_ELM_NODE take at least a node name. the parameter value is optional and represents the text content. |
| * - \ref ROXML_TXT_NODE ignore the node name. the parameter value represents the text content. |
| * - \ref ROXML_CDATA_NODE ignore the node name. the parameter value represents the text content that will be encapsulated in CDATA tags. |
| * - \ref ROXML_CMT_NODE ignore the node name. the parameter value represents the comment. |
| * - \ref ROXML_PI_NODE take the node name as process-instruction target. the parameter value represents the content of processing-instruction. |
| * - \ref ROXML_ATTR_NODE take an attribute name. and the attribute value as given by parameter value. |
| * - \ref ROXML_NSDEF_NODE take an attribute name (empty string for default namespace). and the namespace value as given by parameter value. |
| * - \ref ROXML_NS_NODE take an attribute name (empty string for default namespace). |
| * |
| * some examples to obtain this xml result file |
| \verbatim |
| <root> |
| <!-- sample XML file --> |
| <item id="42"> |
| <price> |
| 24 |
| </price> |
| </item> |
| </root> |
| \endverbatim |
| * |
| * \code |
| * #include <roxml.h> |
| * |
| * int main(void) |
| * { |
| * node_t *root = roxml_add_node(NULL, 0, ROXML_ELM_NODE, "xml", NULL); |
| * node_t *tmp = roxml_add_node(root, 0, ROXML_CMT_NODE, NULL, "sample XML file"); |
| * tmp = roxml_add_node(root, 0, ROXML_ELM_NODE, "item", NULL); |
| * roxml_add_node(tmp, 0, ROXML_ATTR_NODE, "id", "42"); |
| * tmp = roxml_add_node(tmp, 0, ROXML_ELM_NODE, "price", "24"); |
| * roxml_commit_changes(root, "/tmp/test.xml", NULL, 1); |
| * roxml_close(root); |
| * return 0; |
| * } |
| * \endcode |
| * Or also: |
| * \code |
| * #include <roxml.h> |
| * |
| * int main(void) |
| * { |
| * node_t *root = roxml_add_node(NULL, 0, ROXML_ELM_NODE, "xml", NULL); |
| * node_t *tmp = roxml_add_node(root, 0, ROXML_CMT_NODE, NULL, "sample XML file"); |
| * tmp = roxml_add_node(root, 0, ROXML_ELM_NODE, "item", NULL); |
| * roxml_add_node(tmp, 0, ROXML_ATTR_NODE, "id", "42"); |
| * tmp = roxml_add_node(tmp, 0, ROXML_ELM_NODE, "price", NULL); |
| * tmp = roxml_add_node(tmp, 0, ROXML_TXT_NODE, NULL, "24"); |
| * roxml_commit_changes(root, "/tmp/test.xml", NULL, 1); |
| * roxml_close(root); |
| * return 0; |
| * } |
| * \endcode |
| * |
| * If you need a valid XML doc, just start by adding a corresponding process-instruction. |
| * Example, to obtain this xml file: |
| * \verbatim |
| <?xml version="1.0" encoding="UTF-8"?> |
| <!--sample file--> |
| <doc> |
| basic content |
| <item/> |
| <item/> |
| <item/> |
| </doc> |
| \endverbatim |
| * \code |
| * #include <roxml.h> |
| * |
| * int main(void) |
| * { |
| * node_t *root = roxml_add_node(NULL, 0, ROXML_PI_NODE, "xml", "version=\"1.0\" encoding=\"UTF-8\""); |
| * node_t *node = roxml_add_node(root, 0, ROXML_CMT_NODE, NULL, "sample file"); |
| * node = roxml_add_node(root, 0, ROXML_ELM_NODE, "doc", "basic content"); |
| * roxml_add_node(node, 0, ROXML_ELM_NODE, "item", NULL); |
| * roxml_add_node(node, 0, ROXML_ELM_NODE, "item", NULL); |
| * roxml_add_node(node, 0, ROXML_ELM_NODE, "item", NULL); |
| * roxml_commit_changes(root, "/tmp/test.xml", NULL, 1); |
| * roxml_close(root); |
| * return 0; |
| * } |
| * \endcode |
| */ |
| ROXML_API node_t * roxml_add_node(node_t *parent, int position, int type, char *name, char *value); |
| |
| /** \brief text node getter function |
| * |
| * \fn roxml_get_txt(node_t *n, int nth); |
| * this function return the text content of a node as a \ref ROXML_TXT_NODE |
| * the content of the text node can be read using the roxml_get_content function |
| * \param n the node that contains text |
| * \param nth the nth text node to retrieve |
| * \return the text node or ROXML_INVALID_DOC (NULL) |
| * \see roxml_get_txt_nb |
| * \see roxml_get_nodes |
| * \see roxml_get_content |
| * |
| * example: |
| * given this xml file: |
| * \verbatim |
| <xml> |
| This is |
| <item/> |
| an example |
| <item/> |
| of text nodes |
| </xml> |
| \endverbatim |
| * \code |
| * #include <stdio.h> |
| * #include <roxml.h> |
| * |
| * int main(void) |
| * { |
| * int len; |
| * node_t *root = roxml_load_doc("/tmp/doc.xml"); |
| * node_t *item = roxml_get_chld(root, NULL, 0); |
| * |
| * node_t *text = roxml_get_txt(item, 0); |
| * char * text_content = roxml_get_content(text, NULL, 0, &len); |
| * // HERE text_content is equal to "This is" |
| * printf("text_content = '%s'\n", text_content); |
| * |
| * text = roxml_get_txt(item, 1); |
| * text_content = roxml_get_content(text, NULL, 0, &len); |
| * // HERE text_content is equal to "an example" |
| * printf("text_content = '%s'\n", text_content); |
| * |
| * text = roxml_get_txt(item, 2); |
| * text_content = roxml_get_content(text, NULL, 0, &len); |
| * // HERE text_content is equal to "of text nodes" |
| * printf("text_content = '%s'\n", text_content); |
| * |
| * roxml_close(item); |
| * return 0; |
| * } |
| * \endcode |
| */ |
| ROXML_API node_t * roxml_get_txt(node_t *n, int nth); |
| |
| /** \brief text node number getter function |
| * |
| * \fn roxml_get_txt_nb(node_t *n); |
| * this function return the number of text nodes in |
| * a standard node |
| * \param n the node to search into |
| * \return the number of text node |
| * \see roxml_get_txt |
| */ |
| ROXML_API int roxml_get_txt_nb(node_t *n); |
| |
| /** \brief node deletion function |
| * |
| * \fn roxml_del_node(node_t *n); |
| * this function delete a node from the tree. The node is not really deleted |
| * from the file or buffer until the roxml_commit_changes is called, but it won't be |
| * visible anymore in the XML tree. |
| * \param n the node to delete |
| * \return |
| * \see roxml_add_node |
| * \see roxml_commit_changes |
| * \see roxml_commit_buffer |
| * \see roxml_commit_file |
| * |
| * \warning when removing a nsdef node, all node using this namespace will be updated and inherit their parent namespace |
| */ |
| ROXML_API void roxml_del_node(node_t *n); |
| |
| /** \brief sync function |
| * |
| * \fn roxml_commit_changes(node_t *n, char * dest, char ** buffer, int human); |
| * \deprecated |
| * this function sync changes from the RAM tree to the given buffer or file in human or one-line format |
| * 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. |
| * The tree will be dumped to a file if 'dest' is not null and contains a valid path. |
| * The tree will be dumped to a buffer if 'buffer' is not null. the buffer is allocated by the library |
| * and a pointer to it will be stored into 'buffer'. The allocated buffer can be freed usinf free() |
| * \warning in the case of a tree loaded using roxml_load_doc, the roxml_commit_changes cannot be done to that same file |
| * 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. |
| * |
| * This function is now deprecated and one should use roxml_commit_buffer or roxml_commit_file that achieves the exact same goal. |
| * |
| * \param n the root node of the tree to write |
| * \param dest the path to a file to write tree to |
| * \param buffer the address of a buffer where the tree will be written. This buffer have to be freed after use |
| * \param human 0 for one-line tree, or 1 for human format (using tabs, newlines...) |
| * \return the number of bytes written to file or buffer |
| * \see roxml_commit_buffer |
| * \see roxml_commit_file |
| * |
| * This is a legacy function that proposes the same functionnalities as both |
| * \c roxml_commit_file and \c roxml_commit_buffer. New code should use the |
| * latter functions when needed. |
| * |
| * One should do: |
| * \code |
| * #include <roxml.h> |
| * |
| * int main(void) |
| * { |
| * node_t *root = roxml_add_node(NULL, 0, ROXML_ELM_NODE, "xml", NULL); |
| * node_t *tmp = roxml_add_node(root, 0, ROXML_CMT_NODE, NULL, "sample XML file"); |
| * tmp = roxml_add_node(root, 0, ROXML_ELM_NODE, "item", NULL); |
| * roxml_add_node(tmp, 0, ROXML_ATTR_NODE, "id", "42"); |
| * tmp = roxml_add_node(tmp, 0, ROXML_ELM_NODE, "price", "24"); |
| * roxml_commit_changes(root, "/tmp/test.xml", NULL, 1); |
| * return 0; |
| * } |
| * \endcode |
| * to generate the following xml bloc: |
| \verbatim |
| <root> |
| <!-- sample XML file --> |
| <item id="42"> |
| <price> |
| 24 |
| </price> |
| </item> |
| </root> |
| \endverbatim |
| * or also |
| * \code |
| * #include <roxml.h> |
| * |
| * int main(void) |
| * { |
| * node_t *root = roxml_add_node(NULL, 0, ROXML_ELM_NODE, "xml", NULL); |
| * node_t *tmp = roxml_add_node(root, 0, ROXML_CMT_NODE, NULL, "sample XML file"); |
| * tmp = roxml_add_node(root, 0, ROXML_ELM_NODE, "item", NULL); |
| * roxml_add_node(tmp, 0, ROXML_ATTR_NODE, "id", "42"); |
| * tmp = roxml_add_node(tmp, 0, ROXML_ELM_NODE, "price", "24"); |
| * roxml_commit_changes(root, "/tmp/test.xml", NULL, 0); |
| * roxml_close(root); |
| * return 0; |
| * } |
| * \endcode |
| * to generate the following xml bloc: |
| \verbatim |
| <root><!-- sample XML file --><item id="42"><price>24</price></item></root> |
| \endverbatim |
| * the buffer variant works more or less the same way |
| * \code |
| * #include <stdio.h> |
| * #include <roxml.h> |
| * |
| * int main(void) |
| * { |
| * int len = 0; |
| * char * buffer = NULL; |
| * FILE * file_out; |
| * node_t *root = roxml_add_node(NULL, 0, ROXML_ELM_NODE, "xml", NULL); |
| * node_t *tmp = roxml_add_node(root, 0, ROXML_CMT_NODE, NULL, "sample XML file"); |
| * tmp = roxml_add_node(root, 0, ROXML_ELM_NODE, "item", NULL); |
| * roxml_add_node(tmp, 0, ROXML_ATTR_NODE, "id", "42"); |
| * tmp = roxml_add_node(tmp, 0, ROXML_ELM_NODE, "price", "24"); |
| * |
| * len = roxml_commit_changes(root, NULL, &buffer, 0); |
| * |
| * file_out = fopen("/tmp/test.xml", "w"); |
| * fwrite(buffer, 1, len, file_out); |
| * fclose(file_out); |
| * |
| * roxml_close(root); |
| * return 0; |
| * } |
| * \endcode |
| * to generate the following xml bloc: |
| \verbatim |
| <root><!-- sample XML file --><item id="42"><price>24</price></item></root> |
| \endverbatim |
| * \see roxml_commit_file |
| * \see roxml_commit_buffer |
| * \see roxml_commit_fd |
| */ |
| ROXML_API int roxml_commit_changes(node_t *n, char *buffer, int human); |
| |
| /** \brief sync to named file function |
| * |
| * \fn roxml_commit_file(node_t *n, char * dest, int human); |
| * this function sync changes from the RAM tree to the given file in human or one-line format |
| * 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. |
| * The tree will be dumped to a file if 'dest' is not null and contains a valid path. |
| * \warning in the case of a tree loaded using roxml_load_doc, the roxml_commit_file cannot be done to that same file |
| * 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. |
| * |
| * \param n the root node of the tree to write |
| * \param dest the path to a file to write tree to |
| * \param human 0 for one-line tree, or 1 for human format (using tabs, newlines...) |
| * \return the number of bytes written to file or buffer |
| * |
| * One should do: |
| * \code |
| * #include <roxml.h> |
| * |
| * int main(void) |
| * { |
| * node_t *root = roxml_add_node(NULL, 0, ROXML_ELM_NODE, "xml", NULL); |
| * node_t *tmp = roxml_add_node(root, 0, ROXML_CMT_NODE, NULL, "sample XML file"); |
| * tmp = roxml_add_node(root, 0, ROXML_ELM_NODE, "item", NULL); |
| * roxml_add_node(tmp, 0, ROXML_ATTR_NODE, "id", "42"); |
| * tmp = roxml_add_node(tmp, 0, ROXML_ELM_NODE, "price", "24"); |
| * roxml_commit_file(root, "/tmp/test.xml", 1); |
| * roxml_close(root); |
| * return 0; |
| * } |
| * \endcode |
| * to generate the following xml bloc: |
| \verbatim |
| <root> |
| <!-- sample XML file --> |
| <item id="42"> |
| <price> |
| 24 |
| </price> |
| </item> |
| </root> |
| \endverbatim |
| * or also |
| * \code |
| * #include <roxml.h> |
| * |
| * int main(void) |
| * { |
| * node_t *root = roxml_add_node(NULL, 0, ROXML_ELM_NODE, "xml", NULL); |
| * node_t *tmp = roxml_add_node(root, 0, ROXML_CMT_NODE, NULL, "sample XML file"); |
| * tmp = roxml_add_node(root, 0, ROXML_ELM_NODE, "item", NULL); |
| * roxml_add_node(tmp, 0, ROXML_ATTR_NODE, "id", "42"); |
| * tmp = roxml_add_node(tmp, 0, ROXML_ELM_NODE, "price", "24"); |
| * roxml_commit_file(root, "/tmp/test.xml", 0); |
| * roxml_close(root); |
| * return 0; |
| * } |
| * \endcode |
| * to generate the following xml bloc: |
| \verbatim |
| <root><!-- sample XML file --><item id="42"><price>24</price></item></root> |
| \endverbatim |
| * \see roxml_commit_changes |
| * \see roxml_commit_buffer |
| * \see roxml_commit_fd |
| */ |
| ROXML_API int roxml_commit_file(node_t *n, char *dest, int human); |
| |
| /** \brief sync to a memory buffer function |
| * |
| * \fn roxml_commit_buffer(node_t *n, char ** buffer, int human); |
| * this function syncs changes from the RAM tree to the given buffer in human or one-line format |
| * 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. |
| * The tree will be dumped to a buffer if 'buffer' is not null. the buffer is allocated by the library |
| * and a pointer to it will be stored into 'buffer'. The allocated buffer can be freed using free() |
| * |
| * \param n the root node of the tree to write |
| * \param buffer the address of a buffer where the tree will be written. This buffer have to be freed after use |
| * \param human 0 for one-line tree, or 1 for human format (using indentation, newlines...) |
| * \return the number of bytes written to file or buffer |
| * |
| * One should do: |
| * \code |
| * #include <roxml.h> |
| * |
| * int main(void) |
| * { |
| * char *buffer = NULL; |
| * node_t *root = roxml_add_node(NULL, 0, ROXML_ELM_NODE, "xml", NULL); |
| * node_t *tmp = roxml_add_node(root, 0, ROXML_CMT_NODE, NULL, "sample XML file"); |
| * tmp = roxml_add_node(root, 0, ROXML_ELM_NODE, "item", NULL); |
| * roxml_add_node(tmp, 0, ROXML_ATTR_NODE, "id", "42"); |
| * tmp = roxml_add_node(tmp, 0, ROXML_ELM_NODE, "price", "24"); |
| * roxml_commit_changes(root, &buffer, 1); |
| * roxml_close(root); |
| * return 0; |
| * } |
| * \endcode |
| * to generate the following xml bloc: |
| \verbatim |
| <root> |
| <!-- sample XML file --> |
| <item id="42"> |
| <price> |
| 24 |
| </price> |
| </item> |
| </root> |
| \endverbatim |
| * or also |
| * \code |
| * #include <roxml.h> |
| * |
| * int main(void) |
| * { |
| * char *buffer = NULL; |
| * node_t *root = roxml_add_node(NULL, 0, ROXML_ELM_NODE, "xml", NULL); |
| * node_t *tmp = roxml_add_node(root, 0, ROXML_CMT_NODE, NULL, "sample XML file"); |
| * tmp = roxml_add_node(root, 0, ROXML_ELM_NODE, "item", NULL); |
| * roxml_add_node(tmp, 0, ROXML_ATTR_NODE, "id", "42"); |
| * tmp = roxml_add_node(tmp, 0, ROXML_ELM_NODE, "price", "24"); |
| * roxml_commit_buffer(root, &buffer, 0); |
| * roxml_close(root); |
| * return 0; |
| * } |
| * \endcode |
| * to generate the following xml bloc: |
| \verbatim |
| <root><!-- sample XML file --><item id="42"><price>24</price></item></root> |
| \endverbatim |
| * \see roxml_commit_changes |
| * \see roxml_commit_file |
| * \see roxml_commit_fd |
| */ |
| ROXML_API int roxml_commit_buffer(node_t *n, char **buffer, int human); |
| |
| /** \brief sync to file descriptor function |
| * |
| * \fn roxml_commit_fd(node_t *n, int fd, int human); |
| * this function synchronizes changes from the RAM tree to the given file in human or one-line format. |
| * 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. |
| * The tree will be dumped to a file if fd is a valid file descriptor. |
| * \warning in the case of a tree loaded using roxml_load_doc, the roxml_commit_fd cannot be done to that same file |
| * 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. |
| * |
| * \param n the root node of the tree to write |
| * \param fd the file descriptor to write tree to |
| * \param human 0 for one-line tree, or 1 for human format (using tabs, newlines...) |
| * \return the number of bytes written to file |
| * |
| * The file described by fd is not truncated so this function allows one to append an XML subtree to an existing file. |
| * |
| * One should do: |
| * \code |
| * #include <roxml.h> |
| * |
| * int main(void) |
| * { |
| * int fd = open("/tmp/test.xml", O_TRUNC|O_WRONLY, 0666); |
| * node_t *root = roxml_add_node(NULL, 0, ROXML_ELM_NODE, "xml", NULL); |
| * node_t *tmp = roxml_add_node(root, 0, ROXML_CMT_NODE, NULL, "sample XML file"); |
| * tmp = roxml_add_node(root, 0, ROXML_ELM_NODE, "item", NULL); |
| * roxml_add_node(tmp, 0, ROXML_ATTR_NODE, "id", "42"); |
| * tmp = roxml_add_node(tmp, 0, ROXML_ELM_NODE, "price", "24"); |
| * roxml_commit_fd(root, fd, 1); |
| * roxml_close(root); |
| * close(fd); |
| * return 0; |
| * } |
| * \endcode |
| * to generate the following xml bloc: |
| \verbatim |
| <root> |
| <!-- sample XML file --> |
| <item id="42"> |
| <price> |
| 24 |
| </price> |
| </item> |
| </root> |
| \endverbatim |
| * or also |
| * \code |
| * #include <roxml.h> |
| * |
| * int main(void) |
| * { |
| * int fd = open("/tmp/test.xml", O_TRUNC|O_WRONLY, 0666); |
| * node_t *root = roxml_add_node(NULL, 0, ROXML_ELM_NODE, "xml", NULL); |
| * node_t *tmp = roxml_add_node(root, 0, ROXML_CMT_NODE, NULL, "sample XML file"); |
| * tmp = roxml_add_node(root, 0, ROXML_ELM_NODE, "item", NULL); |
| * roxml_add_node(tmp, 0, ROXML_ATTR_NODE, "id", "42"); |
| * tmp = roxml_add_node(tmp, 0, ROXML_ELM_NODE, "price", "24"); |
| * roxml_commit_fd(root, fd, 0); |
| * roxml_close(root); |
| * close(fd); |
| * return 0; |
| * } |
| * \endcode |
| * to generate the following xml bloc: |
| \verbatim |
| <root><!-- sample XML file --><item id="42"><price>24</price></item></root> |
| \endverbatim |
| * \see roxml_commit_changes |
| * \see roxml_commit_file |
| * \see roxml_commit_buffer |
| */ |
| ROXML_API int roxml_commit_fd(node_t *n, int fd, int human); |
| |
| char *roxml_process_special_characters(char *input); |
| |
| void roxml_init(); |
| void roxml_clean_buffer(); |
| |
| ROXML_API char *roxml_get_ns_name(node_t *n, char *buffer, int bufsize); |
| ROXML_API char *roxml_get_ns_content(node_t *n, char *buffer, int bufsize, int *size); |
| ROXML_API char *roxml_get_node_name(node_t *n, char *buffer, int bufsize); |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif /* ROXML_H */ |