/*******************************************************************************
 * Copyright (C) 2004-2006 Intel Corp. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  - Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 *  - Neither the name of Intel Corp. nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL Intel Corp. OR THE CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *******************************************************************************/

/**
 * @author Anas Nashif
 */
#ifdef HAVE_CONFIG_H
#include <wsman_config.h>
#endif

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>

#include <assert.h>

#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include <libxml/xmlstring.h>

#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>


#include "u/libu.h"
#include "wsman-xml-api.h"
#include "wsman-soap.h"
#include "wsman-xml.h"
#include "wsman-xml-binding.h"


static void destroy_attr_private_data(void *data)
{
	if (data)
		xmlFree(data);
}


static void destroy_node_private_data(void *_data)
{
	iWsNode *data = (iWsNode *) _data;
	if (data) {
		// ??? TBD data->nsQNameList;
		if (data->valText)
			xmlFree(data->valText);
		u_free(data);
	}
}

static void destroy_tree_private_data(xmlNode * node)
{
	while (node) {
		xmlAttrPtr attr = node->properties;

		if (node->_private) {
			destroy_node_private_data(node->_private);
			node->_private = NULL;
		}

		while (attr) {
			if (attr->_private) {
				destroy_attr_private_data(attr->_private);
				attr->_private = NULL;
			}
			attr = attr->next;
		}
		destroy_tree_private_data(node->children);
		node = node->next;
	}
}

static void
myXmlErrorReporting (void *ctx, const char* msg, ...)
{
	va_list args;
	char *string;
	va_start(args, msg);
	string = u_strdup_vprintf (msg, args);
	warning (string);
	va_end(args);

	u_free(string);
}

void xml_parser_initialize()
{
	xmlSetGenericErrorFunc(NULL, myXmlErrorReporting);
}

void xml_parser_destroy()
{
}

int xml_parser_utf8_strlen(char *buf)
{
	return xmlUTF8Strlen(BAD_CAST buf);
}

void xml_parser_doc_to_memory(WsXmlDocH doc, char **buf,
		int *ptrSize, const char *encoding)
{
	if (doc && buf && ptrSize)
		xmlDocDumpMemoryEnc(doc->parserDoc,
				(xmlChar **) buf, ptrSize,
				(!encoding) ? "UTF-8" : encoding);
}

void xml_parser_free_memory(void *ptr)
{
	if (ptr)
		xmlFree(ptr);
}



int xml_parser_create_doc_by_import(WsXmlDocH wsDoc, WsXmlNodeH node)
{
	xmlDocPtr doc;
	xmlNodePtr rootNode;

	if ((doc = xmlNewDoc(BAD_CAST "1.0")) == NULL) {
		if (doc)
			xmlFreeDoc(doc);
		return 0;
	} else {
		doc->_private = wsDoc;
		wsDoc->parserDoc = doc;
		rootNode = xmlDocCopyNode((xmlNodePtr) node, doc, 1);
		xmlDocSetRootElement(doc, rootNode);
		return 1;
	}
}

int xml_parser_create_doc(WsXmlDocH wsDoc, const char *rootName)
{
	int retVal = 0;
	xmlDocPtr doc;
	xmlNodePtr rootNode;

	if ((doc = xmlNewDoc(BAD_CAST "1.0")) == NULL ||
			(rootNode = xmlNewNode(NULL, BAD_CAST rootName)) == NULL) {
		if (doc)
			xmlFreeDoc(doc);
	} else {
		doc->_private = wsDoc;
		wsDoc->parserDoc = doc;
		xmlDocSetRootElement(doc, rootNode);
		retVal = 1;
	}

	return retVal;
}



void xml_parser_destroy_doc(WsXmlDocH wsDoc)
{
	xmlDocPtr xmlDoc = (xmlDocPtr) wsDoc->parserDoc;
	if (xmlDoc != NULL) {
		destroy_tree_private_data(xmlDocGetRootElement(xmlDoc));
		xmlFreeDoc(xmlDoc);
	}
}


WsXmlDocH xml_parser_get_doc(WsXmlNodeH node)
{
	xmlDocPtr xmlDoc = ((xmlDocPtr) node)->doc;
	return (WsXmlDocH) (!xmlDoc ? NULL : xmlDoc->_private);
}


WsXmlNodeH xml_parser_get_root(WsXmlDocH doc)
{
	if (doc->parserDoc != NULL)
		return (WsXmlNodeH) xmlDocGetRootElement((xmlDocPtr) doc->
				parserDoc);
	return NULL;
}

WsXmlDocH
xml_parser_file_to_doc( const char *filename,
		const char *encoding, unsigned long options)
{
	xmlDocPtr xmlDoc;
	WsXmlDocH Doc = NULL;

	xmlDoc = xmlReadFile(filename, encoding,
			XML_PARSE_NONET | XML_PARSE_NSCLEAN);
	if (xmlDoc == NULL) {
		return NULL;
	}
	Doc = (WsXmlDocH) u_zalloc(sizeof(*Doc));
	if (Doc == NULL) {
		xmlFreeDoc(xmlDoc);
		return NULL;
	}
	xmlDoc->_private = Doc;
	Doc->parserDoc = xmlDoc;

	return Doc;

}

WsXmlDocH
xml_parser_memory_to_doc( const char *buf, size_t size,
		const char *encoding, unsigned long options)
{
	WsXmlDocH Doc = NULL;
	xmlDocPtr xmlDoc;
	if (!buf || !size ) {
		return NULL;
	}
	xmlDoc = xmlReadMemory(buf, (int) size, NULL, encoding,
			XML_PARSE_NONET | XML_PARSE_NSCLEAN);
	if (xmlDoc == NULL) {
		return NULL;
	}
	Doc = (WsXmlDocH) u_zalloc(sizeof(*Doc));
	if (Doc == NULL) {
		xmlFreeDoc(xmlDoc);
		return NULL;
	}

	xmlDoc->_private = Doc;
	Doc->parserDoc = xmlDoc;

	return Doc;
}


char *xml_parser_node_query(WsXmlNodeH node, int what)
{
	char *ptr = NULL;
	xmlNodePtr xmlNode = (xmlNodePtr) node;
	iWsNode *wsNode = (iWsNode *) xmlNode->_private;

	switch (what) {
	case XML_TEXT_VALUE:
		if (wsNode == NULL)
			xmlNode->_private = wsNode =
				u_zalloc(sizeof(iWsNode));

		if (wsNode != NULL) {
			if (wsNode->valText == NULL) {
				wsNode->valText =
					(char *) xmlNodeGetContent(xmlNode);
			}
			ptr = wsNode->valText;
		}
		break;
	case XML_LOCAL_NAME:
		ptr = (char *) xmlNode->name;
		break;
	case XML_NS_URI:
		if (xmlNode->ns != NULL)
			ptr = (char *) xmlNode->ns->href;
		break;
	case XML_NS_PREFIX:
		if (xmlNode->ns != NULL)
			ptr = (char *) xmlNode->ns->prefix;
		break;
	default:
		break;
	}

	return ptr;
}


int xml_parser_node_set(WsXmlNodeH node, int what, const char *str)
{
	int retVal = -1;
	xmlNodePtr xmlNode = (xmlNodePtr) node;
	iWsNode *wsNode = (iWsNode *) xmlNode->_private;
	xmlNsPtr xmlNs;

	switch (what) {
	case XML_TEXT_VALUE:
		if (wsNode == NULL)
			xmlNode->_private = wsNode =
				u_zalloc(sizeof(iWsNode));

		if (wsNode != NULL) {
			if (wsNode->valText != NULL) {
				xmlFree(wsNode->valText);
				wsNode->valText = NULL;
			}
			xmlNodeSetContent(xmlNode, BAD_CAST str);
			retVal = 0;
		}
		break;

	case XML_LOCAL_NAME:
		xmlNodeSetName(xmlNode, BAD_CAST str);
		retVal = 0;
		break;

	case XML_NS_URI:
		if ((xmlNs = (xmlNsPtr) xml_parser_ns_find(node, str, NULL, 1,
						1)) != NULL) {
			xmlNode->ns = xmlNs;
			retVal = 0;
		} else
			retVal = 1;
		break;
	default:
		retVal = 1;
		break;
	}

	return retVal;
}



WsXmlNodeH xml_parser_node_get(WsXmlNodeH node, int which)
{
	xmlNodePtr xmlNode = NULL;
	xmlNodePtr base = (xmlNodePtr) node;

	switch (which) {
	case XML_ELEMENT_PARENT:
		xmlNode = base->parent;
		break;
	case XML_ELEMENT_NEXT:
		if ((xmlNode = base->next) != NULL) {
			do {
				if (xmlNode->type == XML_ELEMENT_NODE)
					break;
			}
			while ((xmlNode = xmlNode->next) != NULL);
		}
		break;
	case XML_ELEMENT_PREV:
		if ((xmlNode = base->prev) != NULL) {
			do {
				if (xmlNode->type == XML_ELEMENT_NODE)
					break;
			}
			while ((xmlNode = xmlNode->prev) != NULL);
		}
		break;
	case XML_LAST_CHILD:
	default:
		if (which >= 0 || which == XML_LAST_CHILD) {
			int count = 0;
			xmlNode = base->children;

			while (xmlNode) {
				if (xmlNode->type == XML_ELEMENT_NODE) {
					if (which == XML_LAST_CHILD &&
							xmlNode->next == NULL)
						break;

					if (count == which)
						break;

					count++;
				}
				xmlNode = xmlNode->next;
			}
		} else {
			assert(which >= 0);
		}
		break;
	}
	return (WsXmlNodeH) xmlNode;
}

/* check if namespace is defined (at document root)
 * and evtl. (bAddAtRootIfNotFound!=0) add it to the root node
 */

WsXmlNsH
xml_parser_ns_find(WsXmlNodeH node,
		const char *uri,
		const char *prefix,
		int bWalkUpTree, int bAddAtRootIfNotFound)
{
	xmlNodePtr xmlNode = (xmlNodePtr) node;
	xmlNsPtr xmlNs = NULL;

	while (xmlNode != NULL) {
		xmlNs = xmlNode->nsDef;
		while (xmlNs != NULL) {
			if (uri) {
				if (!strcmp((char *) xmlNs->href, uri))
					break;
			} else if (prefix == NULL) {
				if (xmlNs->prefix == NULL)
					break;
			} else
				if (xmlNs->prefix &&
						!strcmp((char *) xmlNs->prefix, prefix)) {
					break;
				}
			xmlNs = xmlNs->next;
		}
		if (xmlNs != NULL || !bWalkUpTree)
			break;
		xmlNode = xmlNode->parent;
	}

	if (xmlNs == NULL && bAddAtRootIfNotFound) {
		xmlNodePtr xmlRoot =
			xmlDocGetRootElement(((xmlDocPtr) node)->doc);
		char buf[12];

		if (prefix == NULL) {
			ws_xml_make_default_prefix((WsXmlNodeH) xmlRoot,
					uri, buf, sizeof(buf));
			prefix = buf;
		}
		xmlNs =
			(xmlNsPtr) xml_parser_ns_add((WsXmlNodeH) xmlRoot, uri,
					prefix);
	}
	return (WsXmlNsH) xmlNs;
}

char *xml_parser_ns_query(WsXmlNsH ns, int what)
{
	xmlNsPtr xmlNs = (xmlNsPtr) ns;
	char *ptr = NULL;

	switch (what) {
	case XML_NS_URI:
		ptr = (char *) xmlNs->href;
		break;
	case XML_NS_PREFIX:
		ptr = (char *) xmlNs->prefix;
		break;
	default:
		assert(what == XML_NS_URI);
		break;
	}
	return ptr;
}


WsXmlNsH
xml_parser_ns_add(WsXmlNodeH node, const char *uri, const char *prefix)
{
	xmlNsPtr xmlNs = NULL;
	if (node && uri) {
		if ((xmlNs = (xmlNsPtr) xml_parser_ns_find(node, uri, NULL, 0, 0)) != NULL) {
                        /* namespace is known */
			if (xmlNs->prefix != NULL) {
				xmlFree((char *) xmlNs->prefix);
				xmlNs->prefix = NULL;
			}
			if (prefix != NULL) {
				xmlNs->prefix = xmlStrdup(BAD_CAST prefix);
			}
		} else {
                        /* create new namespace entry */
			xmlNs =	xmlNewNs((xmlNodePtr) node, BAD_CAST uri, BAD_CAST prefix);
			/* since the 'xml:' name is supposed to be predefined, the above
                         * function will return NULL when prefix == xml && uri == XML_XML_NAMESPACE.
                         * Compensate for this here.
                         */
			if (xmlNs == NULL && strcmp(prefix,"xml") == 0
                            && strcmp(uri,XML_XML_NAMESPACE)== 0) {
				xmlNs = (xmlNsPtr) u_zalloc(sizeof(xmlNs));
				if (xmlNs == NULL) {
					error("Couldn't create a new Namespace structure");	
					return(NULL);
				}
				xmlNs->type = XML_LOCAL_NAMESPACE;
				xmlNs->href = xmlStrdup(uri);
				xmlNs->prefix = xmlStrdup(prefix);
			}
		}
	}
	return (WsXmlNsH) xmlNs;
}


int xml_parser_ns_remove(WsXmlNodeH node, const char *nsUri)
{
	int retVal = -1;

	if (node && nsUri) {
		xmlNodePtr xmlNode = (xmlNodePtr) node;
		xmlNsPtr xmlNs = xmlNode->nsDef;
		xmlNsPtr prevNs = NULL;

		while (xmlNs != NULL) {
			if ((xmlStrEqual(xmlNs->href, BAD_CAST nsUri))) {
				break;
			}
			prevNs = xmlNs;
			xmlNs = xmlNs->next;
		}

		if (xmlNs != NULL) {
			retVal = 0;
			if (prevNs == NULL)
				xmlNode->nsDef = xmlNs->next;
			else
				prevNs->next = xmlNs->next;
			xmlFreeNs(xmlNs);
		} else
			retVal = 1;
	}
	return retVal;
}



WsXmlNsH xml_parser_ns_get(WsXmlNodeH node, int which)
{
	xmlNodePtr xmlNode = (xmlNodePtr) node;
	xmlNsPtr xmlNs = NULL;

	if (which >= 0) {
		int count = 0;
		xmlNs = xmlNode->nsDef;
		while (xmlNs != NULL) {
			if (which == count)
				break;
			count++;
			xmlNs = xmlNs->next;
		}
	} else {
		assert(which >= 0);
	}
	return (WsXmlNsH) xmlNs;
}


static
int get_ns_count_at_node(xmlNodePtr xmlNode)
{
	int count = 0;
	xmlNsPtr xmlNs = xmlNode->nsDef;

	while (xmlNs != NULL) {
		count++;
		xmlNs = xmlNs->next;
	}
	return count;
}


int xml_parser_get_count(WsXmlNodeH node, int what, int bWalkUpTree)
{
	int count = 0;
	xmlNodePtr xmlNode;
	xmlAttrPtr xmlAttr;

	switch (what) {
	case XML_COUNT_NODE:
		xmlNode = ((xmlNodePtr) node)->children;
		while (xmlNode) {
			if (xmlNode->type == XML_ELEMENT_NODE)
				count++;
			xmlNode = xmlNode->next;
		}
		break;
	case XML_COUNT_ATTR:
		xmlAttr = ((xmlNodePtr) node)->properties;
		while (xmlAttr) {
			count++;
			xmlAttr = xmlAttr->next;
		}
		break;
	case XML_COUNT_NS:
		xmlNode = (xmlNodePtr) node;
		while (xmlNode != NULL) {
			count += get_ns_count_at_node(xmlNode);
			if (!bWalkUpTree)
				break;
			xmlNode = xmlNode->parent;
		}
		break;
	default:
		assert(what == XML_COUNT_NODE || what == XML_COUNT_ATTR ||
				what == XML_COUNT_NS);
		break;
	}

	return count;
}

static xmlNodePtr
make_new_xml_node(xmlNodePtr base,
		const char *uri, const char *name, const char *value, int xmlescape)
{
	xmlNodePtr newNode = NULL;
	xmlNsPtr ns = NULL;
	if (uri == NULL ||
			(ns =
			 (xmlNsPtr) xml_parser_ns_find((WsXmlNodeH) base, uri, NULL, 1,
				 1)) != NULL) {
		if ((newNode = xmlNewNode(ns, BAD_CAST name)) != NULL) {
			if (value != NULL){		
				if (xmlescape == 1)
					xmlNodeAddContent(newNode, BAD_CAST value);
				else
					xmlNodeSetContent(newNode, BAD_CAST value);
			}
			newNode->_private = u_zalloc(sizeof(iWsNode));
		}
	}
	return newNode;
}






WsXmlNodeH
xml_parser_node_add(WsXmlNodeH base,
		int where,
		const char *nsUri,
		const char *localName, const char *value, int xmlescape)
{
	xmlNodePtr xmlBase = (xmlNodePtr) base;
	xmlNodePtr newNode =
		make_new_xml_node((where != XML_ELEMENT_NEXT &&
					where != XML_ELEMENT_PREV)
				? xmlBase : xmlBase->parent, nsUri,
				localName, value, xmlescape);
	if (newNode) {
		switch (where) {
		case XML_ELEMENT_NEXT:
			xmlAddNextSibling((xmlNodePtr) base, newNode);
			break;
		case XML_ELEMENT_PREV:
			xmlAddPrevSibling((xmlNodePtr) base, newNode);
			break;
		case XML_LAST_CHILD:
		default:
			xmlAddChild((xmlNodePtr) base, newNode);
			break;
		}
	}
	return (WsXmlNodeH) newNode;

}

int xml_parser_node_remove(WsXmlNodeH node)
{
	destroy_node_private_data(((xmlNodePtr) node)->_private);
	xmlUnlinkNode((xmlNodePtr) node);
	xmlFreeNode((xmlNodePtr) node);
	return 0;
}


WsXmlAttrH
xml_parser_attr_add(WsXmlNodeH node,
		const char *uri, const char *name, const char *value)
{
	xmlNodePtr xmlNode = (xmlNodePtr) node;
	xmlNsPtr xmlNs =
		(xmlNsPtr) xml_parser_ns_find(node, uri, NULL, 1, 1);
	xmlAttrPtr xmlAttr =
		(xmlAttrPtr) ws_xml_find_node_attr(node, uri, name);

	if (xmlAttr != NULL)
		ws_xml_remove_node_attr((WsXmlAttrH) xmlAttr);

	if (xmlNs == NULL)
		xmlAttr =
			xmlNewProp(xmlNode, BAD_CAST name, BAD_CAST value);
	else
		xmlAttr =
			xmlNewNsProp(xmlNode, xmlNs, BAD_CAST name,
					BAD_CAST value);

	if (xmlAttr != NULL) {
		if (xmlNs == NULL)
			xmlAttr->_private =
				xmlGetProp(xmlNode, BAD_CAST name);
		else
			xmlAttr->_private =
				xmlGetNsProp(xmlNode, BAD_CAST name,
						xmlNs->href);
	}

	return (WsXmlAttrH) xmlAttr;
}



int xml_parser_attr_remove(WsXmlAttrH attr)
{
	xmlAttrPtr xmlAttr = (xmlAttrPtr) attr;
	xmlNodePtr xmlNode = (xmlNodePtr) xmlAttr->parent;
	xmlAttrPtr xmlAttrPrev =
		(xmlNode->properties == xmlAttr) ? NULL : xmlNode->properties;

	while (xmlAttrPrev != NULL && xmlAttrPrev->next != xmlAttr) {
		xmlAttrPrev = xmlAttrPrev->next;
	}
	if (xmlAttrPrev != NULL)
		xmlAttrPrev->next = xmlAttr->next;
	else
		xmlNode->properties = xmlAttr->next;

	xmlNode->parent = NULL;
	xmlNode->next = NULL;

	destroy_attr_private_data((xmlAttrPtr) attr);
	xmlFreeProp((xmlAttrPtr) attr);

	return 0;
}

char *xml_parser_attr_query(WsXmlAttrH attr, int what)
{
	char *ptr = NULL;
	xmlAttrPtr xmlAttr = (xmlAttrPtr) attr;
	switch (what) {
	case XML_LOCAL_NAME:
		ptr = (char *) xmlAttr->name;
		break;
	case XML_NS_URI:
		if (xmlAttr->ns != NULL)
			ptr = (char *) xmlAttr->ns->href;
		break;
	case XML_NS_PREFIX:
		if (xmlAttr->ns != NULL)
			ptr = (char *) xmlAttr->ns->prefix;
		break;
	case XML_TEXT_VALUE:
		if (xmlAttr->_private == NULL) {
			if (xmlAttr->ns == NULL)
				xmlAttr->_private =
					xmlGetProp(xmlAttr->parent,
							xmlAttr->name);
			else
				xmlAttr->_private =
					xmlGetNsProp(xmlAttr->parent,
							xmlAttr->name,
							xmlAttr->ns->href);
		}
		ptr = (char *) xmlAttr->_private;
		break;
	default:
		assert(what == XML_LOCAL_NAME);
		break;
	}
	return ptr;
}



WsXmlAttrH xml_parser_attr_get(WsXmlNodeH node, int which)
{
	xmlNodePtr xmlNode = (xmlNodePtr) node;
	xmlAttrPtr xmlAttr = NULL;

	switch (which) {
	case XML_LAST_CHILD:
	default:
		if (which >= 0 || which == XML_LAST_CHILD) {
			int count = 0;
			xmlAttr = xmlNode->properties;

			while (xmlAttr) {
				if (which == XML_LAST_CHILD &&
						xmlAttr->next == NULL)
					break;

				if (which == count)
					break;

				count++;

				xmlAttr = xmlAttr->next;
			}
		} else {
			assert(which >= 0 || which == XML_LAST_CHILD);
		}
		break;
	}

	return (WsXmlAttrH) xmlAttr;
}



void xml_parser_element_dump(FILE * f, WsXmlDocH doc, WsXmlNodeH node)
{

	xmlNodePtr n = (xmlNodePtr) node;
	xmlDocPtr d = (xmlDocPtr) doc;
	xmlElemDump(f, d, n);
}

void xml_parser_doc_dump(FILE * f, WsXmlDocH doc)
{

	xmlDocPtr d = (xmlDocPtr) doc->parserDoc;
	xmlDocFormatDump(f, d, 1);
	return;
}

void xml_parser_doc_dump_memory(WsXmlDocH doc, char **buf, int *ptrSize)
{

	xmlDocPtr d = (xmlDocPtr) doc->parserDoc;
	xmlDocDumpFormatMemory(d, (xmlChar **) buf, ptrSize, 1);
	return;
}

void xml_parser_doc_dump_memory_enc(WsXmlDocH doc, char **buf, int *ptrSize, const char *encoding)
{

	xmlDocPtr d = (xmlDocPtr) doc->parserDoc;
        xmlDocDumpFormatMemoryEnc(d, (xmlChar **) buf, ptrSize, encoding?encoding:"UTF-8", 1);
	return;
}

static void
register_namespaces(xmlXPathContextPtr ctxt, WsXmlDocH doc,
		WsXmlNodeH node)
{
	xmlNsPtr *nsList, *cur;
	xmlDocPtr d = (xmlDocPtr) doc->parserDoc;


	nsList = xmlGetNsList(d, (xmlNodePtr) node);
	if (nsList == NULL) {
		return;
	}
	for (cur = nsList; *cur != NULL; cur++) {
		if (xmlXPathRegisterNs(ctxt, (*cur)->prefix, (*cur)->href)
				!= 0) {
			return;
		}
	}
	xmlFree(nsList);
}


int xml_parser_check_xpath(WsXmlDocH doc, const char *expression)
{
	xmlXPathObject *obj;
	xmlNodeSetPtr nodeset;
	xmlXPathContextPtr ctxt;
	xmlDocPtr d = (xmlDocPtr) doc->parserDoc;
	int retval = 0;

	ctxt = xmlXPathNewContext(d);
	if (ctxt == NULL) {
		error("failed while creating xpath context");
		return 0;
	}
	register_namespaces(ctxt, doc, xml_parser_get_root(doc));
	obj = xmlXPathEvalExpression(BAD_CAST expression, ctxt);
	if (obj) {
		nodeset = obj->nodesetval;
		if (nodeset && nodeset->nodeNr > 0) {
			int size = nodeset->nodeNr;
			int i;
			xmlNodePtr cur;
			for(i = 0; i < size; ++i) {
				if(nodeset->nodeTab[i]->type == XML_ELEMENT_NODE) {
					cur = nodeset->nodeTab[i];
					if(cur->ns) {
						fprintf(stdout, "= element node \"%s:%s\"\n",
								cur->ns->href, cur->name);
					} else {
						fprintf(stdout, "= element node \"%s\"\n",
								cur->name);
					}
				}
			}

			retval = 1;
		}
		xmlXPathFreeContext(ctxt);
		xmlXPathFreeObject(obj);
	} else {
		return 0;
	}

	return retval;
}



char *xml_parser_get_xpath_value(WsXmlDocH doc, const char *expression)
{
	//int i;
	char *result = NULL;
	xmlXPathObject *obj;
	xmlNodeSetPtr nodeset;
	xmlXPathContextPtr ctxt;
	xmlDocPtr d = (xmlDocPtr) doc->parserDoc;
	WsXmlNodeH body;

	ctxt = xmlXPathNewContext(d);
	if (ctxt == NULL) {
		error("failed while creating xpath context");
		return NULL;
	}
	body = ws_xml_get_soap_body(doc);
	register_namespaces(ctxt, doc, xml_parser_get_root(doc));
	if (ws_xml_get_child(body, 0, NULL, NULL)) {
		register_namespaces(ctxt, doc,
				ws_xml_get_child(body, 0, NULL, NULL));
	}

	obj = xmlXPathEvalExpression(BAD_CAST expression, ctxt);
	if (obj) {
		nodeset = obj->nodesetval;
		if (nodeset && nodeset->nodeNr > 0)
			result = (char *) xmlNodeListGetString(d,
					nodeset->
					nodeTab[0]->
					xmlChildrenNode,
					1);

		xmlXPathFreeContext(ctxt);
		xmlXPathFreeObject(obj);
	} else {
		return NULL;
	}

	return result;
}



void xml_parser_unlink_node(WsXmlNodeH node)
{
	xmlUnlinkNode((xmlNodePtr) node);
	xmlFreeNode((xmlNodePtr) node);
	return;
}

void xml_parser_node_set_lang(WsXmlNodeH node,  const char *lang)
{
	xmlNodeSetLang((xmlNodePtr) node, BAD_CAST lang);
}


void xml_parser_set_ns(WsXmlNodeH r, WsXmlNsH ns, const char *prefix)
{
	xmlSetNs((xmlNodePtr) r, (xmlNsPtr) ns);
}

void xml_parser_copy_node(WsXmlNodeH src, WsXmlNodeH dst)
{
	if (src && dst) {
		xmlNodePtr x = xmlDocCopyNode((xmlNodePtr) src,
				   ((xmlDocPtr) src)->doc, 1);
		if (x)
			xmlAddChild((xmlNodePtr) dst, x);
	}
}
