/* nXml - Copyright (C) 2005-2007 bakunin - Andrea Marchesini
 *                                    <bakunin@autistici.org>
 *
 * 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.
 *
 * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifndef __N_XML_H__
#define __N_XML_H__

#include <curl/curl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#define LIBNXML_VERSION_STRING "0.18.3"

#define LIBNXML_MAJOR_VERSION 0
#define LIBNXML_MINOR_VERSION 18
#define LIBNXML_MICRO_VERSION 3

typedef struct nxml_t nxml_t;
typedef struct nxml_data_t nxml_data_t;
typedef struct nxml_attr_t nxml_attr_t;
typedef struct nxml_doctype_t nxml_doctype_t;
typedef struct nxml_namespace_t nxml_namespace_t;

typedef struct __nxml_private_t __nxml_private_t;
typedef struct __nxml_entity_t __nxml_entity_t;

/** This enum describes the error type of libnxml */
typedef enum {
	NXML_OK = 0,	   /**< No error */
	NXML_ERR_POSIX,	/**< For the correct error, use errno */
	NXML_ERR_PARSER,   /**< Parser error */
	NXML_ERR_DOWNLOAD, /**< Download error */
	NXML_ERR_DATA	  /**< The parameters are incorrect */
} nxml_error_t;

/** This enum describes the type of data element of libnxml */
typedef enum {
	NXML_TYPE_TEXT,			/**< Text element */
	NXML_TYPE_COMMENT,		/**< Comment element */
	NXML_TYPE_ELEMENT,		/**< Data element */
	NXML_TYPE_PI,			/**< PI element */
	NXML_TYPE_ELEMENT_CLOSE /**< Data element - For internal use only */
} nxml_type_t;

/** This enum describes the supported XML version */
typedef enum {
	NXML_VERSION_1_1, /**< XML 1.1 */
	NXML_VERSION_1_0  /**< XML 1.0 */
} nxml_version_t;

/** This enum describes the CharSet of XML document */
typedef enum {
	NXML_CHARSET_UTF8,		/**< UTF8 chatset detected */
	NXML_CHARSET_UTF16LE,   /**< UTF 16 Little Endian detected */
	NXML_CHARSET_UTF16BE,   /**< UTF 16 Big Endian detected */
	NXML_CHARSET_UCS4_1234, /**< UCS 4byte order 1234 detected */
	NXML_CHARSET_UCS4_4321, /**< UCS 3byte order 4321 detected */
	NXML_CHARSET_UCS4_2143, /**< UCS 3byte order 2143 detected */
	NXML_CHARSET_UCS4_3412, /**< UCS 3byte order 3412 detected */
	NXML_CHARSET_UNKNOWN	/**< Unknown format */
} nxml_charset_t;

/**
 * Data struct for any element of XML stream/files
 *
 * \brief
 * Data struct for any element of XML streams/files
 */
struct nxml_data_t
{
	nxml_type_t type; /**< type of this nxml_data_t struct */

	char *value; /**< The value of this data struct */

	nxml_attr_t *attributes; /**< List of attributes of this struct.
	  			 This list exists only if
				 type == NXML_TYPE_ELEMENT */

	nxml_namespace_t *ns;	  /**< Pointer to the correct namespace */
	nxml_namespace_t *ns_list; /**< The namespaces in this element */

	nxml_data_t *children; /**< The children of this data struct */
	nxml_data_t *next;	 /**< The next element */

	nxml_data_t *parent; /**< The parent */
	nxml_t *doc;		 /**< The nxml_t */
};

/**
 * Data struct for any element of attribute of xml element
 *
 * \brief
 * Data struct for any element of attribute of xml element
 */
struct nxml_attr_t
{
	char *name;
	char *value;

	nxml_namespace_t *ns;

	nxml_attr_t *next;
};

/**
 * Data struct for doctype elements
 *
 * \brief
 * Data struct for doctype elements
 */
struct nxml_doctype_t
{
	char *value; /**< The string no parsers */
	char *name;  /**< The name of current doctype */

	nxml_t *doc; /**< The nxml_t */
	nxml_doctype_t *next;
};

/**
 * Data struct for namespace
 *
 * \brief
 * Data struct for namespace
 */
struct nxml_namespace_t
{
	char *prefix;
	char *ns;
	nxml_namespace_t *next;
};

/** Data struct private about entities for internal use only
 *
 * \brief
 * Data struct private about entities for internal use only
 */
struct __nxml_entity_t
{
	char *name;
	char *entity;

	__nxml_entity_t *next;
};

/** Data struct private for internal use only
 *
 * \brief
 * Data struct private for internal use only
 */
struct __nxml_private_t
{
	void (*func)(char *, ...);
	int line;
	int timeout;
	char *proxy;
	char *proxy_authentication;
	char *cacert;
	char *certfile;
	char *password;
	int verifypeer;
	char *authentication;
	char *user_agent;
	char textindent;

	CURLcode curl_error;

	__nxml_entity_t *entities;
};

/**
 * Principal data struct. It describes a XML document and it contains pointers
 * to any other structures.
 *
 * \brief
 * Principal data struct. It describes a XML document and it contains pointers
 * to any other structures */
struct nxml_t
{

	char *file;  /**< XML document filename or url */
	size_t size; /**< Size of XML document in byte */

	nxml_version_t version; /**< XML document version */
	int standalone;			/**< This document is standalone ? */
	char *encoding;			/**< Encoding type */

	nxml_charset_t charset_detected; /**< charset detected when the a
					  XML document is parsed. The document
					  will be convert to UTF-8 */

	nxml_data_t *data;		 /**< The data of XML document */
	nxml_doctype_t *doctype; /**< The doctype of XML document */

	__nxml_private_t priv; /**< For internal use only */
};

/* INIT FUNCTIONS ************************************************************/

/**
 * This function creates a new nxml_t data struct.
 *
 * \param nxml Pointer to a nxml_t data struct. It will be allocated.
 * \return the error code
 */
nxml_error_t nxml_new(nxml_t **nxml);

/**
 * This function creates a new nxml_data_t child of a parent in the data
 * struct. If parent is NULL the child will be created in the root level
 * of XML document.
 *
 * \param nxml Pointer to a nxml_t data struct.
 * \param parent The parent of new data struct child. If it is NULL, the
 * child is in the root level.
 * \param child It is the pointer to the new data struct. If *child is NULL,
 * it will be allocated, else it will be insert as it is.
 * \return the error code
 *
 * \code
 * nxml_data_t *data1, *data2;
 * data1=NULL;
 * nxml_add(nxml, NULL, &data1);
 *
 * data2=(nxml_data_t *)malloc(sizeof(nxml_data_t));
 * nxml_add(nxml, NULL, &data2);
 * \endcode
 */
nxml_error_t nxml_add(nxml_t *nxml,
					  nxml_data_t *parent,
					  nxml_data_t **child);

/**
 * This function removes a nxml_data_t child from a parent in the data
 * struct. If parent is NULL the child will be removed in the root level of
 * XML document. This function doesn't free the child. If you want you can
 * reinsert the child in another parent tree or use the nxml_free_data
 * function.
 *
 * \param nxml Pointer to a nxml_t data struct.
 * \param parent The parent of data struct child. If it is NULL, the
 * child will be searched in the root level.
 * \param child It is the pointer to the child that you want remove
 * \return the error code
 */
nxml_error_t nxml_remove(nxml_t *nxml,
						 nxml_data_t *parent,
						 nxml_data_t *child);

/**
 * This function creates a new nxml_attr_t data of a element in the data
 * struct.
 *
 * \param nxml Pointer to a nxml_t data struct.
 * \param element The element of the new data struct attribute.
 * \param attribute The pointer to the your data struct. If it is NULL it will
 * be allocated, else no.
 * \return the error code
 */
nxml_error_t nxml_add_attribute(nxml_t *nxml,
								nxml_data_t *element,
								nxml_attr_t **attribute);

/**
 * This function removes a nxml_attr_t data of a element. It does not free it
 * so you can reinsert o free it with nxml_free_attribute.
 *
 * \param nxml Pointer to a nxml_t data struct.
 * \param element The element that contains the attribute
 * \param attribute The attribute that you want remove.
 * \return the error code
 */
nxml_error_t nxml_remove_attribute(nxml_t *nxml,
								   nxml_data_t *element,
								   nxml_attr_t *attribute);

/**
 * This function adds a nxml_namespace_t data in a nxml document.
 *
 * \param nxml Pointer to a nxml_t data struct.
 * \param element The element of the new data struct namespace.
 * \param ns The namespace that you want add
 * \return the error code
 */
nxml_error_t nxml_add_namespace(nxml_t *nxml,
								nxml_data_t *element,
								nxml_namespace_t **ns);

/**
 * This function removes a nxml_namespace_t data from a nxml document.
 *
 * \param nxml Pointer to a nxml_t data struct.
 * \param element The element of the new data struct namespace.
 * \param ns The namespace that you want remove
 * \return the error code
 */
nxml_error_t nxml_remove_namespace(nxml_t *nxml,
								   nxml_data_t *element,
								   nxml_namespace_t *ns);

/**
 * This function sets the output function. If you set your function, the
 * parser'll write the error by this function. As default there is not a
 * function. If you want tou can set 'nxml_print_general' function that
 * print to stderr.
 *
 * \param nxml The struct create with nxml_new.
 * \param func Your function. If you don't want the function, set it to NULL.
 * As default a nxml_t element has not a output function.
 * \return the error code
 */
nxml_error_t nxml_set_func(nxml_t *nxml,
						   void (*func)(char *, ...));

void nxml_print_generic(char *, ...);

/**
 * This function sets the timeout in seconds for the download of a remote
 *  XML document. Default is 0 and 0 is no timeout.
 *
 * \param nxml The struct create with nxml_new.
 * \param seconds the timeout in seconds
 * \return the error code
 */
nxml_error_t nxml_set_timeout(nxml_t *nxml,
							  int seconds);

/**
 * This functions sets a proxy server for the downloading procedure.
 *
 * \param nxml The struct create with nxml_new.
 * \param proxy the proxy as a string
 * \param userpwd the user and password in this format user:password
 * \return the error code
 */
nxml_error_t nxml_set_proxy(nxml_t *nxml,
							char *proxy,
							char *userpwd);

/**
 * This functions sets a user/password for a for the download procedure.
 *
 * \param nxml The struct create with nxml_new.
 * \param userpwd the user and password in this format user:password
 * \return the error code
 */
nxml_error_t nxml_set_authentication(nxml_t *nxml,
									 char *userpwd);

/**
 * This functions sets an user agent for a for the download procedure.
 *
 * \param nxml The struct create with nxml_new.
 * \param user_agent The agent
 * \return the error code
 */
nxml_error_t nxml_set_user_agent(nxml_t *nxml,
								 char *user_agent);

/**
 * This functions sets a certificate in the http request. You can set a
 * certificate file and a password.
 *
 * \param nxml The struct create with nxml_new.
 * \param certfile the certfile for the ssl connection (can be NULL)
 * \param password the password of your certifcate (can be NULL)
 * \param cacert the CA certificate to verify peer against (can be NULL)
 * \param verifypeer active/deactive the peer validation
 * \return the error code
 */
nxml_error_t nxml_set_certificate(nxml_t *nxml,
								  char *certfile,
								  char *password,
								  char *cacert,
								  int verifypeer);

/**
 * This function (de)actives the indent of the TEXT elements. Default it is
 * activated.
 *
 * \param nxml The struct create with nxml_new
 * \param textindent If it is != 0, the indent will be activated
 * \return the error code
 */
nxml_error_t nxml_set_textindent(nxml_t *nxml,
								 char textindent);

/* DOWNLOAD *****************************************************************/

/**
 * This function downloads a stream from a http/https/ftp server.
 *
 * \param nxml The struct create with nxml_new.
 * \param url the http file
 * \param buffer a string for the buffer
 * \param size The function sets here the length of the file if it's not NULL.
 * \return a buffer or NULL
 */
nxml_error_t nxml_download_file(nxml_t *nxml,
								char *url,
								char **buffer,
								size_t *size);

/* PARSER FUNCTIONS *********************************************************/

/**
 * This function parses a url. It downloads a url with curl library and
 * parses it.
 *
 * \param nxml the struct create with nxml_new.
 * \param url the url that you want parse.
 * \return the error code
 */
nxml_error_t nxml_parse_url(nxml_t *nxml,
							char *url);

/**
 * This function parses a file.
 *
 * \param nxml the struct create with nxml_new.
 * \param file the file that you want parse.
 * \return the error code
 */
nxml_error_t nxml_parse_file(nxml_t *nxml,
							 char *file);

/**
 * This function parses a buffer in memory.
 *
 * \param nxml the struct create with nxml_new.
 * \param buffer the buffer that you want parse.
 * \param size the size of buffer. If size is 0, the function checks the
 * length of your buffer searching a '\\0'.
 * \return the error code
 */
nxml_error_t nxml_parse_buffer(nxml_t *nxml,
							   char *buffer,
							   size_t size);

/* WRITE FUNCTIONS **********************************************************/

/**
 * This function writes the data struct in a local file.
 *
 * \param nxml the nxml data strut
 * \param file the local file
 * \return the error code
 */
nxml_error_t nxml_write_file(nxml_t *nxml,
							 char *file);

/**
 * This function writes the data struct in a buffer.
 *
 * \code
 * char *buffer;
 * buffer=NULL; // This is important!
 * nxml_write_buffer(nxml, &buffer);
 * \endcode
 *
 * The buffer must be NULL.
 *
 * \param nxml
 * \param buffer the memory buffer
 * \return the error code
 */
nxml_error_t nxml_write_buffer(nxml_t *nxml,
							   char **buffer);

/* FREE FUNCTIONS ************************************************************/

/**
 * This function removes the data in a structure nxml_t and makes it clean for
 * another usage.
 *
 * \param nxml the pointer to you data struct.
 * \return the error code.
 */
nxml_error_t nxml_empty(nxml_t *nxml);

/**
 * This function frees the memory of a nxml_t *element. After the free,
 * your data struct is not useful. If you want erase the internal data, use
 * nxml_empty function
 *
 * \param nxml the pointer to your data struct.
 * \return the error code.
 */
nxml_error_t nxml_free(nxml_t *nxml);

/**
 * This function frees the memory of a nxml_data_t *element and any its
 * children and its attributes.
 *
 * \param data the pointer to you data struct.
 * \return the error code
 */
nxml_error_t nxml_free_data(nxml_data_t *data);

/**
 * This function frees the memory of a nxml_attr_t *element.
 *
 * \param data the pointer to you data struct.
 * \return the error code
 */
nxml_error_t nxml_free_attribute(nxml_attr_t *data);

/**
 * This function frees the memory of a nxml_namespace_t *element.
 *
 * \param data the pointer to you data struct.
 * \return the error code
 */
nxml_error_t nxml_free_namespace(nxml_namespace_t *data);

/* EDIT FUNCTIONS ***********************************************************/

/**
 * This function returns the root element of xml data struct.
 *
 * \code
 * nxml_t *nxml;
 * nxml_data_t *root;
 *
 * nxml_new(&nxml);
 * nxml_parser_file(nxml, "file.xml");
 * nxml_root_element(nxml, &root);
 * printf("%p\n",root);
 * nxml_free(nxml);
 * \endcode
 *
 * \param nxml the data struct
 * \param element the pointer to your nxml_data_t struct
 * \return the error code
 */
nxml_error_t nxml_root_element(nxml_t *nxml,
							   nxml_data_t **element);

/**
 * This function searchs the request element in the children of the data struct.
 *
 * \code
 * nxml_t *nxml;
 * nxml_data_t *root;
 *
 * nxml_new(&nxml);
 * nxml_parser_file(nxml, "file.xml");
 * nxml_find_element(nxml, NULL, "hello_world", &root);
 * printf("%p\n",root);
 * nxml_free(nxml);
 * \endcode
 *
 * \param nxml the data struct
 * \param parent the data struct nxml_data_t of parent. If it is NULL, this
 * function searchs in the root element level.
 * \param name the name of the node that you want.
 * \param element the pointer to your nxml_data_t struct. If element will be
 * NULL, the item that you want does not exist.
 * \return the error code
 */
nxml_error_t nxml_find_element(nxml_t *nxml,
							   nxml_data_t *parent,
							   char *name,
							   nxml_data_t **element);

/**
 * This function searchs the first doctype element in the nxml_t document.
 *
 * \param nxml the data struct
 * \param doctype the pointer to your nxml_doctype_t struct. If element will be
 * NULL, the item that you want does not exist.
 * \return the error code
 */
nxml_error_t nxml_doctype_element(nxml_t *nxml,
								  nxml_doctype_t **doctype);

/**
 * This function searchs the request attribute and returns its values.
 *
 * \code
 * nxml_t *nxml;
 * nxml_data_t *root;
 *
 * nxml_new(&nxml);
 * nxml_parser_file(nxml, "file.xml");
 * nxml_find_element(nxml, NULL, "hello_world", &root);
 * if(root) {
 *   nxml_attr_t *attribute=NULL;
 *   nxml_find_attribute(root, "attribute", &attribute);
 *
 *   if(attribute)
 *     printf("%s\n",attribute->value);
 * }
 * nxml_free(nxml);
 * \endcode
 *
 * \param data the data struct
 * \param name the attribute that you want search
 * \param attribute the pointer to your nxml_attr_t struct. If attribute will
 * be NULL, the attribute that you want does not exist.
 * does not exist.
 * \return the error code
 */
nxml_error_t nxml_find_attribute(nxml_data_t *data,
								 char *name,
								 nxml_attr_t **attribute);

/**
 * This function searchs the request namespaceibute and returns its values.
 *
 * \param data the data struct
 * \param name the namespace that you want search
 * \param ns the pointer to your nxml_attr_t struct. If namespace will
 * be NULL, the namespace that you want does not exist.
 * does not exist.
 * \return the error code
 */
nxml_error_t nxml_find_namespace(nxml_data_t *data,
								 char *name,
								 nxml_namespace_t **ns);

/**
 * This function returns the string of a XML element.
 * \code
 * nxml_t *nxml;
 * nxml_data_t *root;
 * char *str;
 *
 * nxml_new(&nxml);
 * nxml_parser_file(nxml, "file.xml");
 * nxml_find_element(nxml, NULL, "hello_world", &root);
 * if(root) {
 *   nxml_get_string(root, &str);
 *   if(str) {
 *     printf("Hello_world item contains: %s\n",str);
 *     free(str);
 *   }
 * }
 * nxml_free(nxml);
 * \endcode
 *
 * \param element the xnml_data_t pointer
 * \param string the pointer to you char *. You must free it after usage.
 * \return the error code
 */
nxml_error_t nxml_get_string(nxml_data_t *element,
							 char **string);

/* ERROR FUNCTIONS **********************************************************/

/**
 * This function returns a static string with the description of error code
 *
 * \param nxml the pointer to data struct
 * \param err the error code that you need as string
 * \return a string. Don't free this string!
 */
char *nxml_strerror(nxml_t *nxml,
					nxml_error_t err);

/**
 * This function returns the CURLcode error if there was a problem about the
 * downloading procedure:
 *
 * \param nxml the pointer to data struct
 * \param err the error code that you need as string
 * \return the CURLcode
 */
CURLcode nxml_curl_error(nxml_t *nxml,
						 nxml_error_t err);

/**
 * This function return the line of a error of parse.
 *
 * \param nxml the pointer to data struct
 * \param line pointer to your integer. In this pointer will be set the line.
 * \return the error code
 */
nxml_error_t nxml_line_error(nxml_t *nxml,
							 int *line);

/* EASY FUNCTIONS ***********************************************************/

/**
 * This function returns a new nxml_t data.
 *
 * \param err If err is not NULL, err will be set to the error flag.
 * \return the pointer to a new nxml_t data. If it returns NULL, read the err
 * code. This function use nxml_set_func with nxml_print_generic so the
 * error will be write in the standard output.
 */
nxml_t *nxmle_new_data(nxml_error_t *err);

/**
 * This function returns a new nxml_t data and parses a remote url document
 * from http or ftp protocol. This function use nxml_set_func with
 * nxml_print_generic so the error will be write in the standard output.
 *
 * \param url the url that you want parse.
 * \param err If err is not NULL, err will be set to the error flag.
 * \return the pointer to a new nxml_t data.
 */
nxml_t *nxmle_new_data_from_url(char *url,
								nxml_error_t *err);

/**
 * This function returns a new nxml_t data and parses a local file. This
 * function use nxml_set_func with nxml_print_generic so the error will be
 * write in the standard output.
 *
 * \param file the file that you want parse.
 * \param err If err is not NULL, err will be set to the error flag.
 * \return the pointer to a new nxml_t data.
 */
nxml_t *nxmle_new_data_from_file(char *file,
								 nxml_error_t *err);

/**
 * This function returns a new nxml_t data and parses a buffer. This
 * function use nxml_set_func with nxml_print_generic so the error will be
 * write in the standard output.
 *
 * \param buffer the buffer that you want parse.
 * \param size the size of buffer. If size is 0, the function checks the
 * \param err If err is not NULL, err will be set to the error flag.
 * \return the pointer to a new nxml_t data.
 */
nxml_t *nxmle_new_data_from_buffer(char *buffer,
								   size_t size,
								   nxml_error_t *err);

/**
 * This function creates and adds a child nxml_data_t to a parent in your
 * nxml data struct.
 *
 * \param nxml Pointer to your nxml data.
 * \param parent The parent of new data struct child. If it is NULL, the
 * child is in the root level.
 * \param err If err is not NULL, err will be set to the error flag.
 * \return the pointer to a new nxml_data_t data child.
 */
nxml_data_t *nxmle_add_new(nxml_t *nxml,
						   nxml_data_t *parent,
						   nxml_error_t *err);

/**
 * This function adds a your nxml_data_t to a parent in your nxml
 * data struct.
 *
 * \param nxml Pointer to your nxml data.
 * \param parent The parent of new data struct child. If it is NULL, the
 * child is in the root level.
 * \param child The you child nxml_data_t struct that you want insert.
 * \param err If err is not NULL, err will be set to the error flag.
 * \return the pointer to a new nxml_data_t data child.
 */
nxml_data_t *nxmle_add_data(nxml_t *nxml,
							nxml_data_t *parent,
							nxml_data_t *child,
							nxml_error_t *err);

/**
 * This function creates and adds an attribute nxml_attr_t data to a
 * nxml_data_t struct in your nxml data struct.
 *
 * \param nxml Pointer to your nxml data.
 * \param element The parent of new nxml_attr_t struct.
 * \param err If err is not NULL, err will be set to the error flag.
 * \return the pointer to a new nxml_data_t data child.
 */
nxml_attr_t *nxmle_add_attribute_new(nxml_t *nxml,
									 nxml_data_t *element,
									 nxml_error_t *err);

/**
 * This function adds an attribute nxml_attr_t data to a
 * nxml_data_t struct in your nxml data struct.
 *
 * \param nxml Pointer to your nxml data.
 * \param element The parent of your nxml_attr_t struct.
 * \param attribute Your attribute element.
 * \param err If err is not NULL, err will be set to the error flag.
 * \return the pointer to a new nxml_data_t data child.
 */
nxml_attr_t *nxmle_add_attribute_data(nxml_t *nxml,
									  nxml_data_t *element,
									  nxml_attr_t *attribute,
									  nxml_error_t *err);

/**
 * This function creates and adds a namespace nxml_namespace_t data to a
 * nxml data struct.
 *
 * \param nxml Pointer to your nxml data.
 * \param element The element of in witch you want add the namespace.
 * \param err If err is not NULL, err will be set to the error flag.
 * \return the pointer to a new nxml_data_t data child.
 */
nxml_namespace_t *nxmle_add_namespace_new(nxml_t *nxml,
										  nxml_data_t *element,
										  nxml_error_t *err);

/**
 * This function adds an namespace nxml_namespace-t data to a nxml data struct.
 *
 * \param nxml Pointer to your nxml data.
 * \param element The element of in witch you want add the namespace.
 * \param ns Your namespace element.
 * \param err If err is not NULL, err will be set to the error flag.
 * \return the pointer to a new nxml_data_t data child.
 */
nxml_namespace_t *nxmle_add_namespace_data(nxml_t *nxml,
										   nxml_data_t *element,
										   nxml_namespace_t *ns,
										   nxml_error_t *err);

/**
 * This function returns the root element of a nxml_t.
 *
 * \param nxml Pointer to your nxml data.
 * \param err If err is not NULL, err will be set to the error flag.
 * \return the pointer to the root element. If NULL the element does not
 * exist.
 */
nxml_data_t *nxmle_root_element(nxml_t *nxml,
								nxml_error_t *err);

/**
 * This function returns the first doctype element of a nxml_t.
 *
 * \param nxml Pointer to your nxml data.
 * \param err If err is not NULL, err will be set to the error flag.
 * \return the pointer to the doctype element. If NULL the element does not
 * exist.
 */
nxml_doctype_t *nxmle_doctype_element(nxml_t *nxml,
									  nxml_error_t *err);

/**
 * This function returns the nxml_data_t pointer to a element by
 * a name.
 *
 * \param nxml Pointer to your nxml data.
 * \param parent Pointer to your nxml_data_t parent. If it is NULL, this
 * function searchs in a root element level.
 * \param name The name of element that you want.
 * \param err If err is not NULL, err will be set to the error flag.
 * \return the pointer to the root element. If NULL the element does not
 * exist.
 */
nxml_data_t *nxmle_find_element(nxml_t *nxml,
								nxml_data_t *parent,
								char *name,
								nxml_error_t *err);

/**
 * This function returns the value of a attribute by a name.
 *
 * \param element Pointer to your nxml_data_t.
 * \param name The name of attribute that you want.
 * \param err If err is not NULL, err will be set to the error flag.
 * \return a pointer to a char allocated so you must free it after usage. If
 * it is NULL, the attribute does not exist.
 */
char *nxmle_find_attribute(nxml_data_t *element,
						   char *name,
						   nxml_error_t *err);

/**
 * This function returns the value of a namespace by a name.
 *
 * \param element Pointer to your nxml_data_t.
 * \param name The name of namespace that you want.
 * \param err If err is not NULL, err will be set to the error flag.
 * \return a pointer to a char allocated so you must free it after usage. If
 * it is NULL, the namespace does not exist.
 */
char *nxmle_find_namespace(nxml_data_t *element,
						   char *name,
						   nxml_error_t *err);

/**
 * This function returns the contain of a element.
 *
 * \param element Pointer to your nxml_data_t.
 * \param err If err is not NULL, err will be set to the error flag.
 * \return a pointer to a char allocated so you must free it after usage. If
 * it is NULL, the attribute does not exist.
 */
char *nxmle_get_string(nxml_data_t *element,
					   nxml_error_t *err);

/**
 * This function writes the data struct in a buffer.
 *
 * \param nxml
 * \param err If err is not NULL, err will be set to the error flag.
 * \return a pointer to a char allocated so you must free it after usage.
 */
char *nxmle_write_buffer(nxml_t *nxml, nxml_error_t *err);

/**
 * This function return the line of a error of parse.
 * \param nxml the pointer to data struct
 * \param err If err is not NULL, err will be set to the error flag.
 * \return the line with the error.
 */
int nxmle_line_error(nxml_t *nxml, nxml_error_t *err);

/* Easy functions defined: */
#define nxmle_remove nxml_remove
#define nxmle_remove_attribute nxml_remove_attribute
#define nxmle_remove_namespace nxml_remove_namespace
#define nxmle_write_file nxml_write_file

#define nxmle_empty nxml_empty
#define nxmle_free nxml_free
#define nxmle_free_data nxml_free_data
#define nxmle_free_attribute nxml_free_attribute

#define nxmle_strerror nxml_strerror

#include "nxml_internal.h"

#endif

/* EOF */
