File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / dom / node.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 20:03:42 2014 UTC (10 years, 10 months ago) by misho
Branches: php, MAIN
CVS tags: v5_4_29, HEAD
php 5.4.29

    1: /*
    2:    +----------------------------------------------------------------------+
    3:    | PHP Version 5                                                        |
    4:    +----------------------------------------------------------------------+
    5:    | Copyright (c) 1997-2014 The PHP Group                                |
    6:    +----------------------------------------------------------------------+
    7:    | This source file is subject to version 3.01 of the PHP license,      |
    8:    | that is bundled with this package in the file LICENSE, and is        |
    9:    | available through the world-wide-web at the following url:           |
   10:    | http://www.php.net/license/3_01.txt                                  |
   11:    | If you did not receive a copy of the PHP license and are unable to   |
   12:    | obtain it through the world-wide-web, please send a note to          |
   13:    | license@php.net so we can mail you a copy immediately.               |
   14:    +----------------------------------------------------------------------+
   15:    | Authors: Christian Stocker <chregu@php.net>                          |
   16:    |          Rob Richards <rrichards@php.net>                            |
   17:    +----------------------------------------------------------------------+
   18: */
   19: 
   20: /* $Id: node.c,v 1.1.1.4 2014/06/15 20:03:42 misho Exp $ */
   21: 
   22: #ifdef HAVE_CONFIG_H
   23: #include "config.h"
   24: #endif
   25: 
   26: #include "php.h"
   27: #if HAVE_LIBXML && HAVE_DOM
   28: #include "php_dom.h"
   29: 
   30: /* {{{ arginfo */
   31: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_insert_before, 0, 0, 1)
   32: 	ZEND_ARG_OBJ_INFO(0, newChild, DOMNode, 0)
   33: 	ZEND_ARG_OBJ_INFO(0, refChild, DOMNode, 1)
   34: ZEND_END_ARG_INFO();
   35: 
   36: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_replace_child, 0, 0, 2)
   37: 	ZEND_ARG_OBJ_INFO(0, newChild, DOMNode, 0)
   38: 	ZEND_ARG_OBJ_INFO(0, oldChild, DOMNode, 0)
   39: ZEND_END_ARG_INFO();
   40: 
   41: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_remove_child, 0, 0, 1)
   42: 	ZEND_ARG_OBJ_INFO(0, oldChild, DOMNode, 0)
   43: ZEND_END_ARG_INFO();
   44: 
   45: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_append_child, 0, 0, 1)
   46: 	ZEND_ARG_OBJ_INFO(0, newChild, DOMNode, 0)
   47: ZEND_END_ARG_INFO();
   48: 
   49: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_has_child_nodes, 0, 0, 0)
   50: ZEND_END_ARG_INFO();
   51: 
   52: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_clone_node, 0, 0, 1)
   53: 	ZEND_ARG_INFO(0, deep)
   54: ZEND_END_ARG_INFO();
   55: 
   56: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_normalize, 0, 0, 0)
   57: ZEND_END_ARG_INFO();
   58: 
   59: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_is_supported, 0, 0, 2)
   60: 	ZEND_ARG_INFO(0, feature)
   61: 	ZEND_ARG_INFO(0, version)
   62: ZEND_END_ARG_INFO();
   63: 
   64: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_has_attributes, 0, 0, 0)
   65: ZEND_END_ARG_INFO();
   66: 
   67: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_compare_document_position, 0, 0, 1)
   68: 	ZEND_ARG_OBJ_INFO(0, other, DOMNode, 0)
   69: ZEND_END_ARG_INFO();
   70: 
   71: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_is_same_node, 0, 0, 1)
   72: 	ZEND_ARG_OBJ_INFO(0, other, DOMNode, 0)
   73: ZEND_END_ARG_INFO();
   74: 
   75: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_lookup_prefix, 0, 0, 1)
   76: 	ZEND_ARG_INFO(0, namespaceURI)
   77: ZEND_END_ARG_INFO();
   78: 
   79: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_is_default_namespace, 0, 0, 1)
   80: 	ZEND_ARG_INFO(0, namespaceURI)
   81: ZEND_END_ARG_INFO();
   82: 
   83: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_lookup_namespace_uri, 0, 0, 1)
   84: 	ZEND_ARG_INFO(0, prefix)
   85: ZEND_END_ARG_INFO();
   86: 
   87: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_is_equal_node, 0, 0, 1)
   88: 	ZEND_ARG_OBJ_INFO(0, arg, DOMNode, 0)
   89: ZEND_END_ARG_INFO();
   90: 
   91: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_get_feature, 0, 0, 2)
   92: 	ZEND_ARG_INFO(0, feature)
   93: 	ZEND_ARG_INFO(0, version)
   94: ZEND_END_ARG_INFO();
   95: 
   96: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_set_user_data, 0, 0, 3)
   97: 	ZEND_ARG_INFO(0, key)
   98: 	ZEND_ARG_INFO(0, data)
   99: 	ZEND_ARG_INFO(0, handler)
  100: ZEND_END_ARG_INFO();
  101: 
  102: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_get_user_data, 0, 0, 1)
  103: 	ZEND_ARG_INFO(0, key)
  104: ZEND_END_ARG_INFO();
  105: 
  106: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_getNodePath, 0, 0, 0)
  107: ZEND_END_ARG_INFO();
  108: 
  109: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_getLineNo, 0, 0, 0)
  110: ZEND_END_ARG_INFO();
  111: 
  112: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_C14N, 0, 0, 0)
  113: 	ZEND_ARG_INFO(0, exclusive)
  114: 	ZEND_ARG_INFO(0, with_comments)
  115: 	ZEND_ARG_ARRAY_INFO(0, xpath, 1)
  116: 	ZEND_ARG_ARRAY_INFO(0, ns_prefixes, 1)
  117: ZEND_END_ARG_INFO();
  118: 
  119: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_C14NFile, 0, 0, 1)
  120: 	ZEND_ARG_INFO(0, uri)
  121: 	ZEND_ARG_INFO(0, exclusive)
  122: 	ZEND_ARG_INFO(0, with_comments)
  123: 	ZEND_ARG_ARRAY_INFO(0, xpath, 1)
  124: 	ZEND_ARG_ARRAY_INFO(0, ns_prefixes, 1)
  125: ZEND_END_ARG_INFO();
  126: /* }}} */
  127: 
  128: /*
  129: * class DOMNode 
  130: *
  131: * URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1950641247
  132: * Since: 
  133: */
  134: 
  135: const zend_function_entry php_dom_node_class_functions[] = { /* {{{ */
  136: 	PHP_FALIAS(insertBefore, dom_node_insert_before, arginfo_dom_node_insert_before)
  137: 	PHP_FALIAS(replaceChild, dom_node_replace_child, arginfo_dom_node_replace_child)
  138: 	PHP_FALIAS(removeChild, dom_node_remove_child, arginfo_dom_node_remove_child)
  139: 	PHP_FALIAS(appendChild, dom_node_append_child, arginfo_dom_node_append_child)
  140: 	PHP_FALIAS(hasChildNodes, dom_node_has_child_nodes, arginfo_dom_node_has_child_nodes)
  141: 	PHP_FALIAS(cloneNode, dom_node_clone_node, arginfo_dom_node_clone_node)
  142: 	PHP_FALIAS(normalize, dom_node_normalize, arginfo_dom_node_normalize)
  143: 	PHP_FALIAS(isSupported, dom_node_is_supported, arginfo_dom_node_is_supported)
  144: 	PHP_FALIAS(hasAttributes, dom_node_has_attributes, arginfo_dom_node_has_attributes)
  145: 	PHP_FALIAS(compareDocumentPosition, dom_node_compare_document_position, arginfo_dom_node_compare_document_position)
  146: 	PHP_FALIAS(isSameNode, dom_node_is_same_node, arginfo_dom_node_is_same_node)
  147: 	PHP_FALIAS(lookupPrefix, dom_node_lookup_prefix, arginfo_dom_node_lookup_prefix)
  148: 	PHP_FALIAS(isDefaultNamespace, dom_node_is_default_namespace, arginfo_dom_node_is_default_namespace)
  149: 	PHP_FALIAS(lookupNamespaceUri, dom_node_lookup_namespace_uri, arginfo_dom_node_lookup_namespace_uri)
  150: 	PHP_FALIAS(isEqualNode, dom_node_is_equal_node, arginfo_dom_node_is_equal_node)
  151: 	PHP_FALIAS(getFeature, dom_node_get_feature, arginfo_dom_node_get_feature)
  152: 	PHP_FALIAS(setUserData, dom_node_set_user_data, arginfo_dom_node_set_user_data)
  153: 	PHP_FALIAS(getUserData, dom_node_get_user_data, arginfo_dom_node_get_user_data)
  154: 	PHP_ME(domnode, getNodePath, arginfo_dom_node_getNodePath, ZEND_ACC_PUBLIC)
  155: 	PHP_ME(domnode, getLineNo, arginfo_dom_node_getLineNo, ZEND_ACC_PUBLIC)
  156: 	PHP_ME(domnode, C14N, arginfo_dom_node_C14N, ZEND_ACC_PUBLIC)
  157: 	PHP_ME(domnode, C14NFile, arginfo_dom_node_C14NFile, ZEND_ACC_PUBLIC)
  158: 	PHP_FE_END
  159: };
  160: /* }}} */
  161: 
  162: static void dom_reconcile_ns(xmlDocPtr doc, xmlNodePtr nodep) /* {{{ */
  163: {
  164: 	xmlNsPtr nsptr, nsdftptr, curns, prevns = NULL;
  165: 
  166: 	if (nodep->type == XML_ELEMENT_NODE) {
  167: 		/* Following if block primarily used for inserting nodes created via createElementNS */
  168: 		if (nodep->nsDef != NULL) {
  169: 			curns = nodep->nsDef;
  170: 			while (curns) {
  171: 				nsdftptr = curns->next;
  172: 				if (curns->href != NULL) {
  173: 					if((nsptr = xmlSearchNsByHref(doc, nodep->parent, curns->href)) && 
  174: 						(curns->prefix == NULL || xmlStrEqual(nsptr->prefix, curns->prefix))) {
  175: 						curns->next = NULL;
  176: 						if (prevns == NULL) {
  177: 							nodep->nsDef = nsdftptr;
  178: 						} else {
  179: 							prevns->next = nsdftptr;
  180: 						}
  181: 						dom_set_old_ns(doc, curns);
  182: 						curns = prevns;
  183: 					}
  184: 				}
  185: 				prevns = curns;
  186: 				curns = nsdftptr;
  187: 			}
  188: 		}
  189: 		xmlReconciliateNs(doc, nodep);
  190: 	}
  191: }
  192: /* }}} */
  193: 
  194: /* {{{ nodeName	string	
  195: readonly=yes 
  196: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-F68D095
  197: Since: 
  198: */
  199: int dom_node_node_name_read(dom_object *obj, zval **retval TSRMLS_DC)
  200: {
  201: 	xmlNode *nodep;
  202: 	xmlNsPtr ns;
  203: 	char *str = NULL;
  204: 	xmlChar *qname = NULL;
  205: 
  206: 	nodep = dom_object_get_node(obj);
  207: 
  208: 	if (nodep == NULL) {
  209: 		php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
  210: 		return FAILURE;
  211: 	}
  212: 
  213: 	switch (nodep->type) {
  214: 		case XML_ATTRIBUTE_NODE:
  215: 		case XML_ELEMENT_NODE:
  216: 			ns = nodep->ns;
  217: 			if (ns != NULL && ns->prefix) {
  218: 				qname = xmlStrdup(ns->prefix);
  219: 				qname = xmlStrcat(qname, ":");
  220: 				qname = xmlStrcat(qname, nodep->name);
  221: 				str = qname;
  222: 			} else {
  223: 				str = (char *) nodep->name;
  224: 			}
  225: 			break;
  226: 		case XML_NAMESPACE_DECL:
  227: 			ns = nodep->ns;
  228: 			if (ns != NULL && ns->prefix) {
  229: 				qname = xmlStrdup("xmlns");
  230: 				qname = xmlStrcat(qname, ":");
  231: 				qname = xmlStrcat(qname, nodep->name);
  232: 				str = qname;
  233: 			} else {
  234: 				str = (char *) nodep->name;
  235: 			}
  236: 			break;
  237: 		case XML_DOCUMENT_TYPE_NODE:
  238: 		case XML_DTD_NODE:
  239: 		case XML_PI_NODE:
  240: 		case XML_ENTITY_DECL:
  241: 		case XML_ENTITY_REF_NODE:
  242: 		case XML_NOTATION_NODE:
  243: 			str = (char *) nodep->name;
  244: 			break;
  245: 		case XML_CDATA_SECTION_NODE:
  246: 			str = "#cdata-section";
  247: 			break;
  248: 		case XML_COMMENT_NODE:
  249: 			str = "#comment";
  250: 			break;
  251: 		case XML_HTML_DOCUMENT_NODE:
  252: 		case XML_DOCUMENT_NODE:
  253: 			str = "#document";
  254: 			break;
  255: 		case XML_DOCUMENT_FRAG_NODE:
  256: 			str = "#document-fragment";
  257: 			break;
  258: 		case XML_TEXT_NODE:
  259: 			str = "#text";
  260: 			break;
  261: 		default:
  262: 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Node Type");
  263: 	}
  264: 
  265: 	ALLOC_ZVAL(*retval);
  266: 
  267: 	if(str != NULL) {
  268: 		ZVAL_STRING(*retval, str, 1);
  269: 	} else {
  270: 		ZVAL_EMPTY_STRING(*retval);
  271: 	}
  272: 	
  273: 	if (qname != NULL) {
  274: 		xmlFree(qname);
  275: 	}
  276: 
  277: 	return SUCCESS;
  278: 
  279: }
  280: 
  281: /* }}} */
  282: 
  283: /* {{{ nodeValue	string	
  284: readonly=no 
  285: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-F68D080
  286: Since: 
  287: */
  288: int dom_node_node_value_read(dom_object *obj, zval **retval TSRMLS_DC)
  289: {
  290: 	xmlNode *nodep;
  291: 	char *str = NULL;
  292: 
  293: 	nodep = dom_object_get_node(obj);
  294: 
  295: 	if (nodep == NULL) {
  296: 		php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
  297: 		return FAILURE;
  298: 	}
  299: 
  300: 	/* Access to Element node is implemented as a convience method */
  301: 	switch (nodep->type) {
  302: 		case XML_ATTRIBUTE_NODE:
  303: 		case XML_TEXT_NODE:
  304: 		case XML_ELEMENT_NODE:
  305: 		case XML_COMMENT_NODE:
  306: 		case XML_CDATA_SECTION_NODE:
  307: 		case XML_PI_NODE:
  308: 			str = xmlNodeGetContent(nodep);
  309: 			break;
  310: 		case XML_NAMESPACE_DECL:
  311: 			str = xmlNodeGetContent(nodep->children);
  312: 			break;
  313: 		default:
  314: 			str = NULL;
  315: 			break;
  316: 	}
  317: 
  318: 	ALLOC_ZVAL(*retval);
  319: 
  320: 	if(str != NULL) {
  321: 		ZVAL_STRING(*retval, str, 1);
  322: 		xmlFree(str);
  323: 	} else {
  324: 		ZVAL_NULL(*retval);
  325: 	}
  326: 
  327: 
  328: 	return SUCCESS;
  329: 
  330: }
  331: 
  332: int dom_node_node_value_write(dom_object *obj, zval *newval TSRMLS_DC)
  333: {
  334: 	xmlNode *nodep;
  335: 	zval value_copy;
  336: 
  337: 	nodep = dom_object_get_node(obj);
  338: 
  339: 	if (nodep == NULL) {
  340: 		php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
  341: 		return FAILURE;
  342: 	}
  343: 
  344: 	/* Access to Element node is implemented as a convience method */
  345: 	switch (nodep->type) {
  346: 		case XML_ELEMENT_NODE:
  347: 		case XML_ATTRIBUTE_NODE:
  348: 			if (nodep->children) {
  349: 				node_list_unlink(nodep->children TSRMLS_CC);
  350: 			}
  351: 		case XML_TEXT_NODE:
  352: 		case XML_COMMENT_NODE:
  353: 		case XML_CDATA_SECTION_NODE:
  354: 		case XML_PI_NODE:
  355: 			if (newval->type != IS_STRING) {
  356: 				if(Z_REFCOUNT_P(newval) > 1) {
  357: 					value_copy = *newval;
  358: 					zval_copy_ctor(&value_copy);
  359: 					newval = &value_copy;
  360: 				}
  361: 				convert_to_string(newval);
  362: 			}
  363: 			xmlNodeSetContentLen(nodep, Z_STRVAL_P(newval), Z_STRLEN_P(newval) + 1);
  364: 			if (newval == &value_copy) {
  365: 				zval_dtor(newval);
  366: 			}
  367: 			break;
  368: 		default:
  369: 			break;
  370: 	}
  371: 
  372: 	return SUCCESS;
  373: }
  374: 
  375: /* }}} */
  376: 
  377: /* {{{ nodeType	int
  378: readonly=yes 
  379: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-111237558
  380: Since:
  381: */
  382: int dom_node_node_type_read(dom_object *obj, zval **retval TSRMLS_DC)
  383: {
  384: 	xmlNode *nodep;
  385: 
  386: 	nodep = dom_object_get_node(obj);
  387: 
  388: 	if (nodep == NULL) {
  389: 		php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
  390: 		return FAILURE;
  391: 	}
  392: 
  393: 	ALLOC_ZVAL(*retval);
  394: 
  395: 	/* Specs dictate that they are both type XML_DOCUMENT_TYPE_NODE */
  396: 	if (nodep->type == XML_DTD_NODE) {
  397: 		ZVAL_LONG(*retval, XML_DOCUMENT_TYPE_NODE);
  398: 	} else {
  399: 		ZVAL_LONG(*retval, nodep->type);
  400: 	}
  401: 
  402: 	return SUCCESS;
  403: }
  404: 
  405: /* }}} */
  406: 
  407: /* {{{ parentNode	DomNode	
  408: readonly=yes 
  409: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1060184317
  410: Since: 
  411: */
  412: int dom_node_parent_node_read(dom_object *obj, zval **retval TSRMLS_DC)
  413: {
  414: 	xmlNode *nodep, *nodeparent;
  415: 	int ret;
  416: 
  417: 	nodep = dom_object_get_node(obj);
  418: 
  419: 	if (nodep == NULL) {
  420: 		php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
  421: 		return FAILURE;
  422: 	}
  423: 
  424: 	ALLOC_ZVAL(*retval);
  425: 
  426: 	nodeparent = nodep->parent;
  427: 	if (!nodeparent) {
  428: 		ZVAL_NULL(*retval);
  429: 		return SUCCESS;
  430: 	}
  431: 
  432: 	if (NULL == (*retval = php_dom_create_object(nodeparent, &ret, *retval, obj TSRMLS_CC))) {
  433: 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
  434: 		return FAILURE;
  435: 	}
  436: 	return SUCCESS;
  437: }
  438: 
  439: /* }}} */
  440: 
  441: /* {{{ childNodes	DomNodeList	
  442: readonly=yes 
  443: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1451460987
  444: Since: 
  445: */
  446: int dom_node_child_nodes_read(dom_object *obj, zval **retval TSRMLS_DC)
  447: {
  448: 	xmlNode *nodep;
  449: 	dom_object *intern;
  450: 
  451: 	nodep = dom_object_get_node(obj);
  452: 
  453: 	if (nodep == NULL) {
  454: 		php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
  455: 		return FAILURE;
  456: 	}
  457: 
  458: 	ALLOC_ZVAL(*retval);
  459: 	
  460: 	if (dom_node_children_valid(nodep) == FAILURE) {
  461: 		ZVAL_NULL(*retval);
  462: 	} else {
  463: 		php_dom_create_interator(*retval, DOM_NODELIST TSRMLS_CC);
  464: 		intern = (dom_object *)zend_objects_get_address(*retval TSRMLS_CC);
  465: 		dom_namednode_iter(obj, XML_ELEMENT_NODE, intern, NULL, NULL, NULL TSRMLS_CC);
  466: 	}
  467: 
  468: 	return SUCCESS;
  469: }
  470: 
  471: /* }}} */
  472: 
  473: /* {{{ firstChild DomNode	
  474: readonly=yes 
  475: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-169727388
  476: Since: 
  477: */
  478: int dom_node_first_child_read(dom_object *obj, zval **retval TSRMLS_DC)
  479: {
  480: 	xmlNode *nodep, *first = NULL;
  481: 	int ret;
  482: 
  483: 	nodep = dom_object_get_node(obj);
  484: 
  485: 	if (nodep == NULL) {
  486: 		php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
  487: 		return FAILURE;
  488: 	}
  489: 
  490: 	if (dom_node_children_valid(nodep) == SUCCESS) {
  491: 		first = nodep->children;
  492: 	}
  493: 
  494: 	ALLOC_ZVAL(*retval);
  495: 
  496: 	if (!first) {
  497: 		ZVAL_NULL(*retval);
  498: 		return SUCCESS;
  499: 	}
  500: 
  501: 	if (NULL == (*retval = php_dom_create_object(first, &ret, *retval, obj TSRMLS_CC))) {
  502: 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
  503: 		return FAILURE;
  504: 	}
  505: 	return SUCCESS;
  506: }
  507: 
  508: /* }}} */
  509: 
  510: /* {{{ lastChild	DomNode	
  511: readonly=yes 
  512: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-61AD09FB
  513: Since: 
  514: */
  515: int dom_node_last_child_read(dom_object *obj, zval **retval TSRMLS_DC)
  516: {
  517: 	xmlNode *nodep, *last = NULL;
  518: 	int ret;
  519: 
  520: 	nodep = dom_object_get_node(obj);
  521: 
  522: 	if (nodep == NULL) {
  523: 		php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
  524: 		return FAILURE;
  525: 	}
  526: 
  527: 	if (dom_node_children_valid(nodep) == SUCCESS) {
  528: 		last = nodep->last;
  529: 	}
  530: 
  531: 	ALLOC_ZVAL(*retval);
  532: 
  533: 	if (!last) {
  534: 		ZVAL_NULL(*retval);
  535: 		return SUCCESS;
  536: 	}
  537: 
  538: 	if (NULL == (*retval = php_dom_create_object(last, &ret, *retval, obj TSRMLS_CC))) {
  539: 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
  540: 		return FAILURE;
  541: 	}
  542: 	return SUCCESS;
  543: }
  544: 
  545: /* }}} */
  546: 
  547: /* {{{ previousSibling	DomNode	
  548: readonly=yes 
  549: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-640FB3C8
  550: Since: 
  551: */
  552: int dom_node_previous_sibling_read(dom_object *obj, zval **retval TSRMLS_DC)
  553: {
  554: 	xmlNode *nodep, *prevsib;
  555: 	int ret;
  556: 
  557: 	nodep = dom_object_get_node(obj);
  558: 
  559: 	if (nodep == NULL) {
  560: 		php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
  561: 		return FAILURE;
  562: 	}
  563: 
  564: 	ALLOC_ZVAL(*retval);
  565: 
  566: 	prevsib = nodep->prev;
  567: 	if (!prevsib) {
  568: 		ZVAL_NULL(*retval);
  569: 		return SUCCESS;
  570: 	}
  571: 
  572: 	if (NULL == (*retval = php_dom_create_object(prevsib, &ret, *retval, obj TSRMLS_CC))) {
  573: 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
  574: 		return FAILURE;
  575: 	}
  576: 	return SUCCESS;
  577: }
  578: 
  579: /* }}} */
  580: 
  581: /* {{{ nextSibling	DomNode
  582: readonly=yes 
  583: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6AC54C2F
  584: Since:
  585: */
  586: int dom_node_next_sibling_read(dom_object *obj, zval **retval TSRMLS_DC)
  587: {
  588: 	xmlNode *nodep, *nextsib;
  589: 	int ret;
  590: 
  591: 	nodep = dom_object_get_node(obj);
  592: 
  593: 	if (nodep == NULL) {
  594: 		php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
  595: 		return FAILURE;
  596: 	}
  597: 
  598: 	nextsib = nodep->next;
  599: 	if (!nextsib) {
  600: 		return FAILURE;
  601: 	}
  602: 
  603: 	ALLOC_ZVAL(*retval);
  604: 
  605: 	if (NULL == (*retval = php_dom_create_object(nextsib, &ret, *retval, obj TSRMLS_CC))) {
  606: 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
  607: 		return FAILURE;
  608: 	}
  609: 	return SUCCESS;
  610: }
  611: 
  612: /* }}} */
  613: 
  614: /* {{{ attributes	DomNamedNodeMap	
  615: readonly=yes 
  616: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-84CF096
  617: Since: 
  618: */
  619: int dom_node_attributes_read(dom_object *obj, zval **retval TSRMLS_DC)
  620: {
  621: 	xmlNode *nodep;
  622: 	dom_object *intern;
  623: 
  624: 	nodep = dom_object_get_node(obj);
  625: 
  626: 	if (nodep == NULL) {
  627: 		php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
  628: 		return FAILURE;
  629: 	}
  630: 
  631: 	ALLOC_ZVAL(*retval);
  632: 
  633: 	if (nodep->type == XML_ELEMENT_NODE) {
  634: 		php_dom_create_interator(*retval, DOM_NAMEDNODEMAP TSRMLS_CC);
  635: 		intern = (dom_object *)zend_objects_get_address(*retval TSRMLS_CC);
  636: 		dom_namednode_iter(obj, XML_ATTRIBUTE_NODE, intern, NULL, NULL, NULL TSRMLS_CC);
  637: 	} else {
  638: 		ZVAL_NULL(*retval);
  639: 	}
  640: 
  641: 	return SUCCESS;
  642: }
  643: 
  644: /* }}} */
  645: 
  646: /* {{{ ownerDocument	DomDocument	
  647: readonly=yes 
  648: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-node-ownerDoc
  649: Since: 
  650: */
  651: int dom_node_owner_document_read(dom_object *obj, zval **retval TSRMLS_DC)
  652: {
  653: 	xmlNode *nodep;
  654: 	xmlDocPtr docp;
  655: 	int ret;
  656: 
  657: 	nodep = dom_object_get_node(obj);
  658: 
  659: 	if (nodep == NULL) {
  660: 		php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
  661: 		return FAILURE;
  662: 	}
  663: 
  664: 	if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
  665: 		ALLOC_ZVAL(*retval);
  666: 		ZVAL_NULL(*retval);
  667: 		return SUCCESS;
  668: 	}
  669: 
  670: 	docp = nodep->doc;
  671: 	if (!docp) {
  672: 		return FAILURE;
  673: 	}
  674: 
  675: 	ALLOC_ZVAL(*retval);
  676: 
  677: 	if (NULL == (*retval = php_dom_create_object((xmlNodePtr) docp, &ret, *retval, obj TSRMLS_CC))) {
  678: 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
  679: 		return FAILURE;
  680: 	}
  681: 	return SUCCESS;
  682: }
  683: 
  684: /* }}} */
  685: 
  686: /* {{{ namespaceUri	string	
  687: readonly=yes 
  688: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-NodeNSname
  689: Since: DOM Level 2
  690: */
  691: int dom_node_namespace_uri_read(dom_object *obj, zval **retval TSRMLS_DC)
  692: {
  693: 	xmlNode *nodep;
  694: 	char *str = NULL;
  695: 
  696: 	nodep = dom_object_get_node(obj);
  697: 
  698: 	if (nodep == NULL) {
  699: 		php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
  700: 		return FAILURE;
  701: 	}
  702: 
  703: 	switch (nodep->type) {
  704: 		case XML_ELEMENT_NODE:
  705: 		case XML_ATTRIBUTE_NODE:
  706: 		case XML_NAMESPACE_DECL:
  707: 			if (nodep->ns != NULL) {
  708: 				str = (char *) nodep->ns->href;
  709: 			}
  710: 			break;
  711: 		default:
  712: 			str = NULL;
  713: 			break;
  714: 	}
  715: 
  716: 	ALLOC_ZVAL(*retval);
  717: 
  718: 	if(str != NULL) {
  719: 		ZVAL_STRING(*retval, str, 1);
  720: 	} else {
  721: 		ZVAL_NULL(*retval);
  722: 	}
  723: 
  724: 	return SUCCESS;
  725: }
  726: 
  727: /* }}} */
  728: 
  729: /* {{{ prefix	string	
  730: readonly=no 
  731: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-NodeNSPrefix
  732: Since: DOM Level 2
  733: */
  734: int dom_node_prefix_read(dom_object *obj, zval **retval TSRMLS_DC)
  735: {
  736: 	xmlNode *nodep;
  737: 	xmlNsPtr ns;
  738: 	char *str = NULL;
  739: 
  740: 	nodep = dom_object_get_node(obj);
  741: 
  742: 	if (nodep == NULL) {
  743: 		php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
  744: 		return FAILURE;
  745: 	}
  746: 
  747: 	switch (nodep->type) {
  748: 		case XML_ELEMENT_NODE:
  749: 		case XML_ATTRIBUTE_NODE:
  750: 		case XML_NAMESPACE_DECL:
  751: 			ns = nodep->ns;
  752: 			if (ns != NULL && ns->prefix) {
  753: 				str = (char *) ns->prefix;
  754: 			}
  755: 			break;
  756: 		default:
  757: 			str = NULL;
  758: 			break;
  759: 	}
  760: 
  761: 	ALLOC_ZVAL(*retval);
  762: 
  763: 	if (str == NULL) {
  764: 		ZVAL_EMPTY_STRING(*retval);
  765: 	} else {
  766: 		ZVAL_STRING(*retval, str, 1);
  767: 	}
  768: 	return SUCCESS;
  769: 
  770: }
  771: 
  772: int dom_node_prefix_write(dom_object *obj, zval *newval TSRMLS_DC)
  773: {
  774: 	zval value_copy;
  775: 	xmlNode *nodep, *nsnode = NULL;
  776: 	xmlNsPtr ns = NULL, curns;
  777: 	char *strURI;
  778: 	char *prefix;
  779: 
  780: 	nodep = dom_object_get_node(obj);
  781: 
  782: 	if (nodep == NULL) {
  783: 		php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
  784: 		return FAILURE;
  785: 	}
  786: 
  787: 	switch (nodep->type) {
  788: 		case XML_ELEMENT_NODE:
  789: 			nsnode = nodep;
  790: 		case XML_ATTRIBUTE_NODE:
  791: 			if (nsnode == NULL) {
  792: 				nsnode = nodep->parent;
  793: 				if (nsnode == NULL) {
  794: 					nsnode = xmlDocGetRootElement(nodep->doc);
  795: 				}
  796: 			}
  797: 			if (newval->type != IS_STRING) {
  798: 				if(Z_REFCOUNT_P(newval) > 1) {
  799: 					value_copy = *newval;
  800: 					zval_copy_ctor(&value_copy);
  801: 					newval = &value_copy;
  802: 				}
  803: 				convert_to_string(newval);
  804: 			}
  805: 			prefix = Z_STRVAL_P(newval);
  806: 			if (nsnode && nodep->ns != NULL && !xmlStrEqual(nodep->ns->prefix, (xmlChar *)prefix)) {
  807: 				strURI = (char *) nodep->ns->href;
  808: 				if (strURI == NULL || 
  809: 					(!strcmp (prefix, "xml") && strcmp(strURI, XML_XML_NAMESPACE)) ||
  810: 					(nodep->type == XML_ATTRIBUTE_NODE && !strcmp (prefix, "xmlns") &&
  811: 					 strcmp (strURI, DOM_XMLNS_NAMESPACE)) ||
  812: 					(nodep->type == XML_ATTRIBUTE_NODE && !strcmp (nodep->name, "xmlns"))) {
  813: 					ns = NULL;
  814: 				} else {
  815: 					curns = nsnode->nsDef;
  816: 					while (curns != NULL) {
  817: 						if (xmlStrEqual((xmlChar *)prefix, curns->prefix) && xmlStrEqual(nodep->ns->href, curns->href)) {
  818: 							ns = curns;
  819: 							break;
  820: 						}
  821: 						curns = curns->next;
  822: 					}
  823: 					if (ns == NULL) {
  824: 						ns = xmlNewNs(nsnode, nodep->ns->href, (xmlChar *)prefix);
  825: 					}
  826: 				}
  827: 
  828: 				if (ns == NULL) {
  829: 					if (newval == &value_copy) {
  830: 						zval_dtor(newval);
  831: 					}
  832: 					php_dom_throw_error(NAMESPACE_ERR, dom_get_strict_error(obj->document) TSRMLS_CC);
  833: 					return FAILURE;
  834: 				}
  835: 
  836: 				xmlSetNs(nodep, ns);
  837: 			}
  838: 			if (newval == &value_copy) {
  839: 				zval_dtor(newval);
  840: 			}
  841: 			break;
  842: 		default:
  843: 			break;
  844: 	}
  845: 
  846: 	return SUCCESS;
  847: }
  848: 
  849: /* }}} */
  850: 
  851: /* {{{ localName	string	
  852: readonly=yes 
  853: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-NodeNSLocalN
  854: Since: DOM Level 2
  855: */
  856: int dom_node_local_name_read(dom_object *obj, zval **retval TSRMLS_DC)
  857: {
  858: 	xmlNode *nodep;
  859: 
  860: 	nodep = dom_object_get_node(obj);
  861: 
  862: 	if (nodep == NULL) {
  863: 		php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
  864: 		return FAILURE;
  865: 	}
  866: 
  867: 	ALLOC_ZVAL(*retval);
  868: 
  869: 	if (nodep->type == XML_ELEMENT_NODE || nodep->type == XML_ATTRIBUTE_NODE || nodep->type == XML_NAMESPACE_DECL) {
  870: 		ZVAL_STRING(*retval, (char *) (nodep->name), 1);
  871: 	} else {
  872: 		ZVAL_NULL(*retval);
  873: 	}
  874: 
  875: 	return SUCCESS;
  876: }
  877: 
  878: /* }}} */
  879: 
  880: /* {{{ baseURI	string
  881: readonly=yes
  882: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-baseURI
  883: Since: DOM Level 3
  884: */
  885: int dom_node_base_uri_read(dom_object *obj, zval **retval TSRMLS_DC)
  886: {
  887: 	xmlNode *nodep;
  888: 	xmlChar *baseuri;
  889: 
  890: 	nodep = dom_object_get_node(obj);
  891: 
  892: 	if (nodep == NULL) {
  893: 		php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
  894: 		return FAILURE;
  895: 	}
  896: 
  897: 	ALLOC_ZVAL(*retval);
  898: 
  899: 	baseuri = xmlNodeGetBase(nodep->doc, nodep);
  900: 	if (baseuri) {
  901: 		ZVAL_STRING(*retval, (char *) (baseuri), 1);
  902: 		xmlFree(baseuri);
  903: 	} else {
  904: 		ZVAL_NULL(*retval);
  905: 	}
  906: 
  907: 	return SUCCESS;
  908: }
  909: 
  910: /* }}} */
  911: 
  912: /* {{{ textContent	string	
  913: readonly=no 
  914: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-textContent
  915: Since: DOM Level 3
  916: */
  917: int dom_node_text_content_read(dom_object *obj, zval **retval TSRMLS_DC)
  918: {
  919: 	xmlNode *nodep;
  920: 	char *str = NULL;
  921: 
  922: 	nodep = dom_object_get_node(obj);
  923: 
  924: 	if (nodep == NULL) {
  925: 		php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
  926: 		return FAILURE;
  927: 	}
  928: 
  929: 	str = xmlNodeGetContent(nodep);
  930: 
  931: 	ALLOC_ZVAL(*retval);
  932: 
  933: 	if(str != NULL) {
  934: 		ZVAL_STRING(*retval, str, 1);
  935: 		xmlFree(str);
  936: 	} else {
  937: 		ZVAL_EMPTY_STRING(*retval);
  938: 	}
  939: 
  940: 	return SUCCESS;
  941: }
  942: 
  943: int dom_node_text_content_write(dom_object *obj, zval *newval TSRMLS_DC)
  944: {
  945: 	return SUCCESS;
  946: }
  947: 
  948: /* }}} */
  949: 
  950: static xmlNodePtr _php_dom_insert_fragment(xmlNodePtr nodep, xmlNodePtr prevsib, xmlNodePtr nextsib, xmlNodePtr fragment, dom_object *intern, dom_object *childobj TSRMLS_DC) /* {{{ */
  951: {
  952: 	xmlNodePtr newchild, node;
  953: 
  954: 	newchild = fragment->children;
  955: 
  956: 	if (newchild) {
  957: 		if (prevsib == NULL) {
  958: 			nodep->children = newchild;
  959: 		} else {
  960: 			prevsib->next = newchild;
  961: 		}
  962: 		newchild->prev = prevsib;
  963: 		if (nextsib == NULL) {
  964: 			nodep->last = fragment->last;
  965: 		} else {
  966: 			fragment->last->next = nextsib;
  967: 			nextsib->prev = fragment->last;
  968: 		}
  969: 
  970: 		node = newchild;
  971: 		while (node != NULL) {
  972: 			node->parent = nodep;
  973: 			if (node->doc != nodep->doc) {
  974: 				xmlSetTreeDoc(node, nodep->doc);
  975: 				if (node->_private != NULL) {
  976: 					childobj = node->_private;
  977: 					childobj->document = intern->document;
  978: 					php_libxml_increment_doc_ref((php_libxml_node_object *)childobj, NULL TSRMLS_CC);
  979: 				}
  980: 			}
  981: 			if (node == fragment->last) {
  982: 				break;
  983: 			}
  984: 			node = node->next;
  985: 		}
  986: 
  987: 		fragment->children = NULL;
  988: 		fragment->last = NULL;
  989: 	}
  990: 
  991: 	return newchild;
  992: }
  993: /* }}} */
  994: 
  995: /* {{{ proto domnode dom_node_insert_before(DomNode newChild, DomNode refChild);
  996: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-952280727
  997: Since:
  998: */
  999: PHP_FUNCTION(dom_node_insert_before)
 1000: {
 1001: 	zval *id, *node, *ref = NULL;
 1002: 	xmlNodePtr child, new_child, parentp, refp;
 1003: 	dom_object *intern, *childobj, *refpobj;
 1004: 	int ret, stricterror;
 1005: 
 1006: 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO|O!", &id, dom_node_class_entry, &node, dom_node_class_entry, &ref, dom_node_class_entry) == FAILURE) {
 1007: 		return;
 1008: 	}
 1009: 
 1010: 	DOM_GET_OBJ(parentp, id, xmlNodePtr, intern);
 1011: 
 1012: 	if (dom_node_children_valid(parentp) == FAILURE) {
 1013: 		RETURN_FALSE;
 1014: 	}
 1015: 
 1016: 	DOM_GET_OBJ(child, node, xmlNodePtr, childobj);
 1017: 
 1018: 	new_child = NULL;
 1019: 
 1020: 	stricterror = dom_get_strict_error(intern->document);
 1021: 
 1022: 	if (dom_node_is_read_only(parentp) == SUCCESS ||
 1023: 		(child->parent != NULL && dom_node_is_read_only(child->parent) == SUCCESS)) {
 1024: 		php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror TSRMLS_CC);
 1025: 		RETURN_FALSE;
 1026: 	}
 1027: 
 1028: 	if (dom_hierarchy(parentp, child) == FAILURE) {
 1029: 		php_dom_throw_error(HIERARCHY_REQUEST_ERR, stricterror TSRMLS_CC);
 1030: 		RETURN_FALSE;
 1031: 	}
 1032: 
 1033: 	if (child->doc != parentp->doc && child->doc != NULL) {
 1034: 		php_dom_throw_error(WRONG_DOCUMENT_ERR, stricterror TSRMLS_CC);
 1035: 		RETURN_FALSE;
 1036: 	}
 1037: 
 1038: 	if (child->type == XML_DOCUMENT_FRAG_NODE && child->children == NULL) {
 1039: 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Document Fragment is empty");
 1040: 		RETURN_FALSE;
 1041: 	}
 1042: 
 1043: 	if (child->doc == NULL && parentp->doc != NULL) {
 1044: 		childobj->document = intern->document;
 1045: 		php_libxml_increment_doc_ref((php_libxml_node_object *)childobj, NULL TSRMLS_CC);
 1046: 	}
 1047: 
 1048: 	if (ref != NULL) {
 1049: 		DOM_GET_OBJ(refp, ref, xmlNodePtr, refpobj);
 1050: 		if (refp->parent != parentp) {
 1051: 			php_dom_throw_error(NOT_FOUND_ERR, stricterror TSRMLS_CC);
 1052: 			RETURN_FALSE;
 1053: 		}
 1054: 
 1055: 		if (child->parent != NULL) {
 1056: 			xmlUnlinkNode(child);
 1057: 		}
 1058: 
 1059: 		if (child->type == XML_TEXT_NODE && (refp->type == XML_TEXT_NODE || 
 1060: 			(refp->prev != NULL && refp->prev->type == XML_TEXT_NODE))) {
 1061: 			if (child->doc == NULL) {
 1062: 				xmlSetTreeDoc(child, parentp->doc);
 1063: 			}
 1064: 			new_child = child;
 1065: 			new_child->parent = refp->parent;
 1066: 			new_child->next = refp;
 1067: 			new_child->prev = refp->prev;
 1068: 			refp->prev = new_child;
 1069: 			if (new_child->prev != NULL) {
 1070: 				new_child->prev->next = new_child;
 1071: 			}
 1072: 			if (new_child->parent != NULL) {
 1073: 				if (new_child->parent->children == refp) {
 1074: 					new_child->parent->children = new_child;
 1075: 				}
 1076: 			}
 1077: 
 1078: 		} else if (child->type == XML_ATTRIBUTE_NODE) {
 1079: 			xmlAttrPtr lastattr;
 1080: 
 1081: 			if (child->ns == NULL)
 1082: 				lastattr = xmlHasProp(refp->parent, child->name);
 1083: 			else
 1084: 				lastattr = xmlHasNsProp(refp->parent, child->name, child->ns->href);
 1085: 			if (lastattr != NULL && lastattr->type != XML_ATTRIBUTE_DECL) {
 1086: 				if (lastattr != (xmlAttrPtr) child) {
 1087: 					xmlUnlinkNode((xmlNodePtr) lastattr);
 1088: 					php_libxml_node_free_resource((xmlNodePtr) lastattr TSRMLS_CC);
 1089: 				} else {
 1090: 					DOM_RET_OBJ(child, &ret, intern);
 1091: 					return;
 1092: 				}
 1093: 			}
 1094: 		} else if (child->type == XML_DOCUMENT_FRAG_NODE) {
 1095: 			new_child = _php_dom_insert_fragment(parentp, refp->prev, refp, child, intern, childobj TSRMLS_CC);
 1096: 		}
 1097: 
 1098: 		if (new_child == NULL) {
 1099: 			new_child = xmlAddPrevSibling(refp, child);
 1100: 		}
 1101: 	} else {
 1102: 		if (child->parent != NULL){
 1103: 			xmlUnlinkNode(child);
 1104: 		}
 1105: 		if (child->type == XML_TEXT_NODE && parentp->last != NULL && parentp->last->type == XML_TEXT_NODE) {
 1106: 			child->parent = parentp;
 1107: 			if (child->doc == NULL) {
 1108: 				xmlSetTreeDoc(child, parentp->doc);
 1109: 			}
 1110: 			new_child = child;
 1111: 			if (parentp->children == NULL) {
 1112: 				parentp->children = child;
 1113: 				parentp->last = child;
 1114: 			} else {
 1115: 				child = parentp->last;
 1116: 				child->next = new_child;
 1117: 				new_child->prev = child;
 1118: 				parentp->last = new_child;
 1119: 			}
 1120: 		} else 	if (child->type == XML_ATTRIBUTE_NODE) {
 1121: 			xmlAttrPtr lastattr;
 1122: 
 1123: 			if (child->ns == NULL)
 1124: 				lastattr = xmlHasProp(parentp, child->name);
 1125: 			else
 1126: 				lastattr = xmlHasNsProp(parentp, child->name, child->ns->href);
 1127: 			if (lastattr != NULL && lastattr->type != XML_ATTRIBUTE_DECL) {
 1128: 				if (lastattr != (xmlAttrPtr) child) {
 1129: 					xmlUnlinkNode((xmlNodePtr) lastattr);
 1130: 					php_libxml_node_free_resource((xmlNodePtr) lastattr TSRMLS_CC);
 1131: 				} else {
 1132: 					DOM_RET_OBJ(child, &ret, intern);
 1133: 					return;
 1134: 				}
 1135: 			}
 1136: 		} else if (child->type == XML_DOCUMENT_FRAG_NODE) {
 1137: 			new_child = _php_dom_insert_fragment(parentp, parentp->last, NULL, child, intern, childobj TSRMLS_CC);
 1138: 		}
 1139: 		if (new_child == NULL) {
 1140: 			new_child = xmlAddChild(parentp, child);
 1141: 		}
 1142: 	}
 1143: 
 1144: 	if (NULL == new_child) {
 1145: 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't add newnode as the previous sibling of refnode");
 1146: 		RETURN_FALSE;
 1147: 	}
 1148: 
 1149: 	dom_reconcile_ns(parentp->doc, new_child);
 1150: 
 1151: 	DOM_RET_OBJ(new_child, &ret, intern);
 1152: 
 1153: }
 1154: /* }}} end dom_node_insert_before */
 1155: 
 1156: /* {{{ proto DomNode dom_node_replace_child(DomNode newChild, DomNode oldChild);
 1157: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-785887307
 1158: Since: 
 1159: */
 1160: PHP_FUNCTION(dom_node_replace_child)
 1161: {
 1162: 	zval *id, *newnode, *oldnode;
 1163: 	xmlNodePtr children, newchild, oldchild, nodep;
 1164: 	dom_object *intern, *newchildobj, *oldchildobj;
 1165: 	int foundoldchild = 0, stricterror;
 1166: 
 1167: 	int ret;
 1168: 
 1169: 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OOO", &id, dom_node_class_entry, &newnode, dom_node_class_entry, &oldnode, dom_node_class_entry) == FAILURE) {
 1170: 		return;
 1171: 	}
 1172: 
 1173: 	DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
 1174: 
 1175: 	if (dom_node_children_valid(nodep) == FAILURE) {
 1176: 		RETURN_FALSE;
 1177: 	}
 1178: 
 1179: 	DOM_GET_OBJ(newchild, newnode, xmlNodePtr, newchildobj);
 1180: 	DOM_GET_OBJ(oldchild, oldnode, xmlNodePtr, oldchildobj);
 1181: 
 1182: 	children = nodep->children;
 1183: 	if (!children) {
 1184: 		RETURN_FALSE;
 1185: 	}
 1186: 
 1187: 	stricterror = dom_get_strict_error(intern->document);
 1188: 
 1189: 	if (dom_node_is_read_only(nodep) == SUCCESS || 
 1190: 		(newchild->parent != NULL && dom_node_is_read_only(newchild->parent) == SUCCESS)) {
 1191: 		php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror TSRMLS_CC);
 1192: 		RETURN_FALSE;
 1193: 	}
 1194: 
 1195: 	if (newchild->doc != nodep->doc && newchild->doc != NULL) {
 1196: 		php_dom_throw_error(WRONG_DOCUMENT_ERR, stricterror TSRMLS_CC);
 1197: 		RETURN_FALSE;
 1198: 	}
 1199: 
 1200: 	if (dom_hierarchy(nodep, newchild) == FAILURE) {
 1201: 		php_dom_throw_error(HIERARCHY_REQUEST_ERR, stricterror TSRMLS_CC);
 1202: 		RETURN_FALSE;
 1203: 	}
 1204: 
 1205: 	/* check for the old child and whether the new child is already a child */
 1206: 	while (children) {
 1207: 		if (children == oldchild) {
 1208: 			foundoldchild = 1;
 1209: 			break;
 1210: 		}
 1211: 		children = children->next;
 1212: 	}
 1213: 
 1214: 	if (foundoldchild) {
 1215: 		if (newchild->type == XML_DOCUMENT_FRAG_NODE) {
 1216: 			xmlNodePtr prevsib, nextsib;
 1217: 			prevsib = oldchild->prev;
 1218: 			nextsib = oldchild->next;
 1219: 
 1220: 			xmlUnlinkNode(oldchild);
 1221: 
 1222: 			newchild = _php_dom_insert_fragment(nodep, prevsib, nextsib, newchild, intern, newchildobj TSRMLS_CC);
 1223: 			if (newchild) {
 1224: 				dom_reconcile_ns(nodep->doc, newchild);
 1225: 			}
 1226: 		} else if (oldchild != newchild) {
 1227: 			if (newchild->doc == NULL && nodep->doc != NULL) {
 1228: 				xmlSetTreeDoc(newchild, nodep->doc);
 1229: 				newchildobj->document = intern->document;
 1230: 				php_libxml_increment_doc_ref((php_libxml_node_object *)newchildobj, NULL TSRMLS_CC);
 1231: 			}
 1232: 			xmlReplaceNode(oldchild, newchild);
 1233: 			dom_reconcile_ns(nodep->doc, newchild);
 1234: 		}
 1235: 		DOM_RET_OBJ(oldchild, &ret, intern);
 1236: 		return;
 1237: 	} else {
 1238: 		php_dom_throw_error(NOT_FOUND_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
 1239: 		RETURN_FALSE;
 1240: 	}
 1241: }
 1242: /* }}} end dom_node_replace_child */
 1243: 
 1244: /* {{{ proto DomNode dom_node_remove_child(DomNode oldChild);
 1245: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1734834066
 1246: Since: 
 1247: */
 1248: PHP_FUNCTION(dom_node_remove_child)
 1249: {
 1250: 	zval *id, *node;
 1251: 	xmlNodePtr children, child, nodep;
 1252: 	dom_object *intern, *childobj;
 1253: 	int ret, stricterror;
 1254: 
 1255: 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_node_class_entry, &node, dom_node_class_entry) == FAILURE) {
 1256: 		return;
 1257: 	}
 1258: 
 1259: 	DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
 1260: 
 1261: 	if (dom_node_children_valid(nodep) == FAILURE) {
 1262: 		RETURN_FALSE;
 1263: 	}
 1264: 
 1265: 	DOM_GET_OBJ(child, node, xmlNodePtr, childobj);
 1266: 
 1267: 	stricterror = dom_get_strict_error(intern->document);
 1268: 
 1269: 	if (dom_node_is_read_only(nodep) == SUCCESS || 
 1270: 		(child->parent != NULL && dom_node_is_read_only(child->parent) == SUCCESS)) {
 1271: 		php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror TSRMLS_CC);
 1272: 		RETURN_FALSE;
 1273: 	}
 1274: 
 1275: 	children = nodep->children;
 1276: 	if (!children) {
 1277: 		php_dom_throw_error(NOT_FOUND_ERR, stricterror TSRMLS_CC);
 1278: 		RETURN_FALSE;
 1279: 	}
 1280: 
 1281: 	while (children) {
 1282: 		if (children == child) {
 1283: 			xmlUnlinkNode(child);
 1284: 			DOM_RET_OBJ(child, &ret, intern);
 1285: 			return;
 1286: 		}
 1287: 		children = children->next;
 1288: 	}
 1289: 
 1290: 	php_dom_throw_error(NOT_FOUND_ERR, stricterror TSRMLS_CC);
 1291: 	RETURN_FALSE
 1292: }
 1293: /* }}} end dom_node_remove_child */
 1294: 
 1295: /* {{{ proto DomNode dom_node_append_child(DomNode newChild);
 1296: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-184E7107
 1297: Since: 
 1298: */
 1299: PHP_FUNCTION(dom_node_append_child)
 1300: {
 1301: 	zval *id, *node;
 1302: 	xmlNodePtr child, nodep, new_child = NULL;
 1303: 	dom_object *intern, *childobj;
 1304: 	int ret, stricterror;
 1305: 
 1306: 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_node_class_entry, &node, dom_node_class_entry) == FAILURE) {
 1307: 		return;
 1308: 	}
 1309: 
 1310: 	DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
 1311: 
 1312: 	if (dom_node_children_valid(nodep) == FAILURE) {
 1313: 		RETURN_FALSE;
 1314: 	}
 1315: 
 1316: 	DOM_GET_OBJ(child, node, xmlNodePtr, childobj);
 1317: 
 1318: 	stricterror = dom_get_strict_error(intern->document);
 1319: 
 1320: 	if (dom_node_is_read_only(nodep) == SUCCESS ||
 1321: 		(child->parent != NULL && dom_node_is_read_only(child->parent) == SUCCESS)) {
 1322: 		php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror TSRMLS_CC);
 1323: 		RETURN_FALSE;
 1324: 	}
 1325: 
 1326: 	if (dom_hierarchy(nodep, child) == FAILURE) {
 1327: 		php_dom_throw_error(HIERARCHY_REQUEST_ERR, stricterror TSRMLS_CC);
 1328: 		RETURN_FALSE;
 1329: 	}
 1330: 
 1331: 	if (!(child->doc == NULL || child->doc == nodep->doc)) {
 1332: 		php_dom_throw_error(WRONG_DOCUMENT_ERR, stricterror TSRMLS_CC);
 1333: 		RETURN_FALSE;
 1334: 	}
 1335: 
 1336: 	if (child->type == XML_DOCUMENT_FRAG_NODE && child->children == NULL) {
 1337: 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Document Fragment is empty");
 1338: 		RETURN_FALSE;
 1339: 	}
 1340: 
 1341: 	if (child->doc == NULL && nodep->doc != NULL) {
 1342: 		childobj->document = intern->document;
 1343: 		php_libxml_increment_doc_ref((php_libxml_node_object *)childobj, NULL TSRMLS_CC);
 1344: 	}
 1345: 
 1346: 	if (child->parent != NULL){
 1347: 		xmlUnlinkNode(child);
 1348: 	}
 1349: 
 1350: 	if (child->type == XML_TEXT_NODE && nodep->last != NULL && nodep->last->type == XML_TEXT_NODE) {
 1351: 		child->parent = nodep;
 1352: 		if (child->doc == NULL) {
 1353: 			xmlSetTreeDoc(child, nodep->doc);
 1354: 		}
 1355: 		new_child = child;
 1356: 		if (nodep->children == NULL) {
 1357: 			nodep->children = child;
 1358: 			nodep->last = child;
 1359: 		} else {
 1360: 			child = nodep->last;
 1361: 			child->next = new_child;
 1362: 			new_child->prev = child;
 1363: 			nodep->last = new_child;
 1364: 		}
 1365: 	} else 	if (child->type == XML_ATTRIBUTE_NODE) {
 1366: 		xmlAttrPtr lastattr;
 1367: 
 1368: 		if (child->ns == NULL)
 1369: 			lastattr = xmlHasProp(nodep, child->name);
 1370: 		else
 1371: 			lastattr = xmlHasNsProp(nodep, child->name, child->ns->href);
 1372: 		if (lastattr != NULL && lastattr->type != XML_ATTRIBUTE_DECL) {
 1373: 			if (lastattr != (xmlAttrPtr) child) {
 1374: 				xmlUnlinkNode((xmlNodePtr) lastattr);
 1375: 				php_libxml_node_free_resource((xmlNodePtr) lastattr TSRMLS_CC);
 1376: 			}
 1377: 		}
 1378: 	} else if (child->type == XML_DOCUMENT_FRAG_NODE) {
 1379: 		new_child = _php_dom_insert_fragment(nodep, nodep->last, NULL, child, intern, childobj TSRMLS_CC);
 1380: 	}
 1381: 
 1382: 	if (new_child == NULL) {
 1383: 		new_child = xmlAddChild(nodep, child);
 1384: 		if (new_child == NULL) {
 1385: 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't append node");
 1386: 			RETURN_FALSE;
 1387: 		}
 1388: 	}
 1389: 
 1390: 	dom_reconcile_ns(nodep->doc, new_child);
 1391: 
 1392: 	DOM_RET_OBJ(new_child, &ret, intern);
 1393: }
 1394: /* }}} end dom_node_append_child */
 1395: 
 1396: /* {{{ proto boolean dom_node_has_child_nodes();
 1397: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-810594187
 1398: Since: 
 1399: */
 1400: PHP_FUNCTION(dom_node_has_child_nodes)
 1401: {
 1402: 	zval *id;
 1403: 	xmlNode *nodep;
 1404: 	dom_object *intern;
 1405: 
 1406: 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_node_class_entry) == FAILURE) {
 1407: 		return;
 1408: 	}
 1409: 
 1410: 	DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
 1411: 
 1412: 	if (dom_node_children_valid(nodep) == FAILURE) {
 1413: 		RETURN_FALSE;
 1414: 	}
 1415: 
 1416: 	if (nodep->children) {
 1417: 		RETURN_TRUE;
 1418: 	} else {
 1419: 		RETURN_FALSE;
 1420: 	}
 1421: }
 1422: /* }}} end dom_node_has_child_nodes */
 1423: 
 1424: /* {{{ proto DomNode dom_node_clone_node(boolean deep);
 1425: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-3A0ED0A4
 1426: Since: 
 1427: */
 1428: PHP_FUNCTION(dom_node_clone_node)
 1429: {
 1430: 	zval *id;
 1431: 	xmlNode *n, *node;
 1432: 	int ret;
 1433: 	dom_object *intern;
 1434: 	long recursive = 0;
 1435: 
 1436: 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|l", &id, dom_node_class_entry, &recursive) == FAILURE) {
 1437: 		return;
 1438: 	}
 1439: 
 1440: 	DOM_GET_OBJ(n, id, xmlNodePtr, intern);
 1441: 
 1442: 	node = xmlDocCopyNode(n, n->doc, recursive);
 1443: 
 1444: 	if (!node) {
 1445: 		RETURN_FALSE;
 1446: 	}
 1447: 
 1448: 	/* When deep is false Element nodes still require the attributes 
 1449: 	Following taken from libxml as xmlDocCopyNode doesnt do this */
 1450: 	if (n->type == XML_ELEMENT_NODE && recursive == 0) {
 1451: 		if (n->nsDef != NULL) {
 1452: 			node->nsDef = xmlCopyNamespaceList(n->nsDef);
 1453: 		}
 1454: 		if (n->ns != NULL) {
 1455: 			xmlNsPtr ns;
 1456: 			ns = xmlSearchNs(n->doc, node, n->ns->prefix);
 1457: 			if (ns == NULL) {
 1458: 				ns = xmlSearchNs(n->doc, n, n->ns->prefix);
 1459: 				if (ns != NULL) {
 1460: 					xmlNodePtr root = node;
 1461: 
 1462: 					while (root->parent != NULL) {
 1463: 						root = root->parent;
 1464: 					}
 1465: 					node->ns = xmlNewNs(root, ns->href, ns->prefix);
 1466: 				}
 1467: 			} else {
 1468: 				node->ns = ns;
 1469: 			}
 1470: 		}
 1471: 		if (n->properties != NULL) {
 1472: 			node->properties = xmlCopyPropList(node, n->properties);
 1473: 		}
 1474: 	}
 1475: 
 1476: 	/* If document cloned we want a new document proxy */
 1477: 	if (node->doc != n->doc) {
 1478: 		intern = NULL;
 1479: 	}
 1480: 
 1481: 	DOM_RET_OBJ(node, &ret, intern);
 1482: }
 1483: /* }}} end dom_node_clone_node */
 1484: 
 1485: /* {{{ proto void dom_node_normalize();
 1486: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-normalize
 1487: Since: 
 1488: */
 1489: PHP_FUNCTION(dom_node_normalize)
 1490: {
 1491: 	zval *id;
 1492: 	xmlNode *nodep;
 1493: 	dom_object *intern;
 1494: 
 1495: 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_node_class_entry) == FAILURE) {
 1496: 		return;
 1497: 	}
 1498: 
 1499: 	DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
 1500: 
 1501: 	dom_normalize(nodep TSRMLS_CC);
 1502: 
 1503: }
 1504: /* }}} end dom_node_normalize */
 1505: 
 1506: /* {{{ proto boolean dom_node_is_supported(string feature, string version);
 1507: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Level-2-Core-Node-supports
 1508: Since: DOM Level 2
 1509: */
 1510: PHP_FUNCTION(dom_node_is_supported)
 1511: {
 1512: 	zval *id;
 1513: 	int feature_len, version_len;
 1514: 	char *feature, *version;
 1515: 
 1516: 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss", &id, dom_node_class_entry, &feature, &feature_len, &version, &version_len) == FAILURE) {
 1517: 		return;
 1518: 	}
 1519: 
 1520: 	if (dom_has_feature(feature, version)) {
 1521: 		RETURN_TRUE;
 1522: 	} else {
 1523: 		RETURN_FALSE;
 1524: 	}
 1525: }
 1526: /* }}} end dom_node_is_supported */
 1527: 
 1528: /* {{{ proto boolean dom_node_has_attributes();
 1529: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-NodeHasAttrs
 1530: Since: DOM Level 2
 1531: */
 1532: PHP_FUNCTION(dom_node_has_attributes)
 1533: {
 1534: 	zval *id;
 1535: 	xmlNode *nodep;
 1536: 	dom_object *intern;
 1537: 
 1538: 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_node_class_entry) == FAILURE) {
 1539: 		return;
 1540: 	}
 1541: 
 1542: 	DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
 1543: 
 1544: 	if (nodep->type != XML_ELEMENT_NODE)
 1545: 		RETURN_FALSE;
 1546: 
 1547: 	if (nodep->properties) {
 1548: 		RETURN_TRUE;
 1549: 	} else {
 1550: 		RETURN_FALSE;
 1551: 	}
 1552: }
 1553: /* }}} end dom_node_has_attributes */
 1554: 
 1555: /* {{{ proto short dom_node_compare_document_position(DomNode other);
 1556: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-compareDocumentPosition
 1557: Since: DOM Level 3
 1558: */
 1559: PHP_FUNCTION(dom_node_compare_document_position)
 1560: {
 1561:  DOM_NOT_IMPLEMENTED();
 1562: }
 1563: /* }}} end dom_node_compare_document_position */
 1564: 
 1565: /* {{{ proto boolean dom_node_is_same_node(DomNode other);
 1566: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-isSameNode
 1567: Since: DOM Level 3
 1568: */
 1569: PHP_FUNCTION(dom_node_is_same_node)
 1570: {
 1571: 	zval *id, *node;
 1572: 	xmlNodePtr nodeotherp, nodep;
 1573: 	dom_object *intern, *nodeotherobj;
 1574: 
 1575: 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_node_class_entry, &node, dom_node_class_entry) == FAILURE) {
 1576: 		return;
 1577: 	}
 1578: 
 1579: 	DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
 1580: 
 1581: 	DOM_GET_OBJ(nodeotherp, node, xmlNodePtr, nodeotherobj);
 1582: 
 1583: 	if (nodep == nodeotherp) {
 1584: 		RETURN_TRUE;
 1585: 	} else {
 1586: 		RETURN_FALSE;
 1587: 	}
 1588: }
 1589: /* }}} end dom_node_is_same_node */
 1590: 
 1591: /* {{{ proto string dom_node_lookup_prefix(string namespaceURI);
 1592: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-lookupNamespacePrefix
 1593: Since: DOM Level 3
 1594: */
 1595: PHP_FUNCTION(dom_node_lookup_prefix)
 1596: {
 1597: 	zval *id;
 1598: 	xmlNodePtr nodep, lookupp = NULL;
 1599: 	dom_object *intern;
 1600: 	xmlNsPtr nsptr;
 1601: 	int uri_len = 0;
 1602: 	char *uri;
 1603: 
 1604: 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_node_class_entry, &uri, &uri_len) == FAILURE) {
 1605: 		return;
 1606: 	}
 1607: 
 1608: 	DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
 1609: 
 1610: 	if (uri_len > 0) {
 1611: 		switch (nodep->type) { 
 1612: 			case XML_ELEMENT_NODE:
 1613: 				lookupp = nodep;
 1614: 				break; 
 1615: 			case XML_DOCUMENT_NODE:
 1616: 			case XML_HTML_DOCUMENT_NODE:
 1617: 				lookupp = xmlDocGetRootElement((xmlDocPtr) nodep);
 1618: 				break;
 1619: 			case XML_ENTITY_NODE : 
 1620: 			case XML_NOTATION_NODE: 
 1621: 			case XML_DOCUMENT_FRAG_NODE: 
 1622: 			case XML_DOCUMENT_TYPE_NODE:
 1623: 			case XML_DTD_NODE:
 1624: 				RETURN_NULL();
 1625: 				break;
 1626: 			default:
 1627: 				lookupp =  nodep->parent;
 1628: 		} 
 1629: 
 1630: 		if (lookupp != NULL && (nsptr = xmlSearchNsByHref(lookupp->doc, lookupp, uri))) {
 1631: 			if (nsptr->prefix != NULL) {
 1632: 				RETURN_STRING((char *) nsptr->prefix, 1);
 1633: 			}
 1634: 		}
 1635: 	}
 1636: 		
 1637: 	RETURN_NULL();
 1638: }
 1639: /* }}} end dom_node_lookup_prefix */
 1640: 
 1641: /* {{{ proto boolean dom_node_is_default_namespace(string namespaceURI);
 1642: URL: http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-isDefaultNamespace
 1643: Since: DOM Level 3
 1644: */
 1645: PHP_FUNCTION(dom_node_is_default_namespace)
 1646: {
 1647: 	zval *id;
 1648: 	xmlNodePtr nodep;
 1649: 	dom_object *intern;
 1650: 	xmlNsPtr nsptr;
 1651: 	int uri_len = 0;
 1652: 	char *uri;
 1653: 
 1654: 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_node_class_entry, &uri, &uri_len) == FAILURE) {
 1655: 		return;
 1656: 	}
 1657: 
 1658: 	DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
 1659: 	if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
 1660: 		nodep = xmlDocGetRootElement((xmlDocPtr) nodep);
 1661: 	}
 1662: 
 1663: 	if (nodep && uri_len > 0) {
 1664: 		nsptr = xmlSearchNs(nodep->doc, nodep, NULL);
 1665: 		if (nsptr && xmlStrEqual(nsptr->href, uri)) {
 1666: 			RETURN_TRUE;
 1667: 		}
 1668: 	}
 1669: 
 1670: 	RETURN_FALSE;
 1671: }
 1672: /* }}} end dom_node_is_default_namespace */
 1673: 
 1674: /* {{{ proto string dom_node_lookup_namespace_uri(string prefix);
 1675: URL: http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespaceURI
 1676: Since: DOM Level 3
 1677: */
 1678: PHP_FUNCTION(dom_node_lookup_namespace_uri)
 1679: {
 1680: 	zval *id;
 1681: 	xmlNodePtr nodep;
 1682: 	dom_object *intern;
 1683: 	xmlNsPtr nsptr;
 1684: 	int prefix_len = 0;
 1685: 	char *prefix=NULL;
 1686: 
 1687: 	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!", &id, dom_node_class_entry, &prefix, &prefix_len) == FAILURE) {
 1688: 		return;
 1689: 	}
 1690: 
 1691: 	DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
 1692: 	if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
 1693: 		nodep = xmlDocGetRootElement((xmlDocPtr) nodep);
 1694: 		if (nodep == NULL) {
 1695: 			RETURN_NULL();
 1696: 		}
 1697: 	}
 1698: 
 1699: 	nsptr = xmlSearchNs(nodep->doc, nodep, prefix);
 1700: 	if (nsptr && nsptr->href != NULL) {
 1701: 		RETURN_STRING((char *) nsptr->href, 1);
 1702: 	}
 1703: 
 1704: 	RETURN_NULL();
 1705: }
 1706: /* }}} end dom_node_lookup_namespace_uri */
 1707: 
 1708: /* {{{ proto boolean dom_node_is_equal_node(DomNode arg);
 1709: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-isEqualNode
 1710: Since: DOM Level 3
 1711: */
 1712: PHP_FUNCTION(dom_node_is_equal_node)
 1713: {
 1714:  DOM_NOT_IMPLEMENTED();
 1715: }
 1716: /* }}} end dom_node_is_equal_node */
 1717: 
 1718: /* {{{ proto DomNode dom_node_get_feature(string feature, string version);
 1719: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-getFeature
 1720: Since: DOM Level 3
 1721: */
 1722: PHP_FUNCTION(dom_node_get_feature)
 1723: {
 1724:  DOM_NOT_IMPLEMENTED();
 1725: }
 1726: /* }}} end dom_node_get_feature */
 1727: 
 1728: /* {{{ proto mixed dom_node_set_user_data(string key, mixed data, userdatahandler handler);
 1729: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-setUserData
 1730: Since: DOM Level 3
 1731: */
 1732: PHP_FUNCTION(dom_node_set_user_data)
 1733: {
 1734:  DOM_NOT_IMPLEMENTED();
 1735: }
 1736: /* }}} end dom_node_set_user_data */
 1737: 
 1738: /* {{{ proto mixed dom_node_get_user_data(string key);
 1739: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-getUserData
 1740: Since: DOM Level 3
 1741: */
 1742: PHP_FUNCTION(dom_node_get_user_data)
 1743: {
 1744:  DOM_NOT_IMPLEMENTED();
 1745: }
 1746: /* }}} end dom_node_get_user_data */
 1747: 
 1748: static void dom_canonicalization(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */
 1749: {
 1750: 	zval *id;
 1751: 	zval *xpath_array=NULL, *ns_prefixes=NULL;
 1752: 	xmlNodePtr nodep;
 1753: 	xmlDocPtr docp;
 1754: 	xmlNodeSetPtr nodeset = NULL;
 1755: 	dom_object *intern;
 1756: 	zend_bool exclusive=0, with_comments=0;
 1757: 	xmlChar **inclusive_ns_prefixes = NULL;
 1758: 	char *file = NULL;
 1759: 	int ret = -1, file_len = 0;
 1760: 	xmlOutputBufferPtr buf;
 1761: 	xmlXPathContextPtr ctxp=NULL;
 1762: 	xmlXPathObjectPtr xpathobjp=NULL;
 1763: 
 1764: 	if (mode == 0) {
 1765: 		if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), 
 1766: 			"O|bba!a!", &id, dom_node_class_entry, &exclusive, &with_comments, 
 1767: 			&xpath_array, &ns_prefixes) == FAILURE) {
 1768: 			return;
 1769: 		}
 1770: 	} else {
 1771: 		if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), 
 1772: 			"Os|bba!a!", &id, dom_node_class_entry, &file, &file_len, &exclusive, 
 1773: 			&with_comments, &xpath_array, &ns_prefixes) == FAILURE) {
 1774: 			return;
 1775: 		}
 1776: 	}
 1777: 
 1778: 	DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
 1779: 
 1780: 	docp = nodep->doc;
 1781: 
 1782: 	if (! docp) {
 1783: 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Node must be associated with a document");
 1784: 		RETURN_FALSE;
 1785: 	}
 1786: 
 1787: 	if (xpath_array == NULL) {
 1788: 		if (nodep->type != XML_DOCUMENT_NODE) {
 1789: 			ctxp = xmlXPathNewContext(docp);
 1790: 			ctxp->node = nodep;
 1791: 			xpathobjp = xmlXPathEvalExpression("(.//. | .//@* | .//namespace::*)", ctxp);
 1792: 			ctxp->node = NULL;
 1793: 			if (xpathobjp && xpathobjp->type == XPATH_NODESET) {
 1794: 				nodeset = xpathobjp->nodesetval;
 1795: 			} else {
 1796: 				if (xpathobjp) {
 1797: 					xmlXPathFreeObject(xpathobjp);
 1798: 				}
 1799: 				xmlXPathFreeContext(ctxp);
 1800: 				php_error_docref(NULL TSRMLS_CC, E_WARNING, "XPath query did not return a nodeset.");
 1801: 				RETURN_FALSE;
 1802: 			}
 1803: 		}
 1804: 	} else {
 1805: 		/*xpath query from xpath_array */
 1806: 		HashTable *ht = Z_ARRVAL_P(xpath_array);
 1807: 		zval **tmp;
 1808: 		char *xquery;
 1809: 
 1810: 		if (zend_hash_find(ht, "query", sizeof("query"), (void**)&tmp) == SUCCESS &&
 1811: 		    Z_TYPE_PP(tmp) == IS_STRING) {
 1812: 			xquery = Z_STRVAL_PP(tmp);
 1813: 		} else {
 1814: 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "'query' missing from xpath array or is not a string");
 1815: 			RETURN_FALSE;
 1816: 		}
 1817: 
 1818: 		ctxp = xmlXPathNewContext(docp);
 1819: 		ctxp->node = nodep;
 1820: 
 1821: 		if (zend_hash_find(ht, "namespaces", sizeof("namespaces"), (void**)&tmp) == SUCCESS &&
 1822: 		    Z_TYPE_PP(tmp) == IS_ARRAY) {
 1823: 			zval **tmpns;
 1824: 			while (zend_hash_get_current_data(Z_ARRVAL_PP(tmp), (void **)&tmpns) == SUCCESS) {
 1825: 				if (Z_TYPE_PP(tmpns) == IS_STRING) {
 1826: 					char *prefix;
 1827: 					ulong idx;
 1828: 					uint prefix_key_len;
 1829: 
 1830: 					if (zend_hash_get_current_key_ex(Z_ARRVAL_PP(tmp), 
 1831: 						&prefix, &prefix_key_len, &idx, 0, NULL) == HASH_KEY_IS_STRING) {
 1832: 						xmlXPathRegisterNs(ctxp, prefix, Z_STRVAL_PP(tmpns));
 1833: 					}
 1834: 				}
 1835: 				zend_hash_move_forward(Z_ARRVAL_PP(tmp));
 1836: 			}
 1837: 		}
 1838: 
 1839: 		xpathobjp = xmlXPathEvalExpression(xquery, ctxp);
 1840: 		ctxp->node = NULL;
 1841: 		if (xpathobjp && xpathobjp->type == XPATH_NODESET) {
 1842: 			nodeset = xpathobjp->nodesetval;
 1843: 		} else {
 1844: 			if (xpathobjp) {
 1845: 				xmlXPathFreeObject(xpathobjp);
 1846: 			}
 1847: 			xmlXPathFreeContext(ctxp);
 1848: 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "XPath query did not return a nodeset.");
 1849: 			RETURN_FALSE;
 1850: 		}
 1851: 	}
 1852: 
 1853: 	if (ns_prefixes != NULL) {
 1854: 		if (exclusive) {
 1855: 			zval **tmpns;
 1856: 			int nscount = 0;
 1857: 
 1858: 			inclusive_ns_prefixes = safe_emalloc(zend_hash_num_elements(Z_ARRVAL_P(ns_prefixes)) + 1,
 1859: 				sizeof(xmlChar *), 0);
 1860: 			while (zend_hash_get_current_data(Z_ARRVAL_P(ns_prefixes), (void **)&tmpns) == SUCCESS) {
 1861: 				if (Z_TYPE_PP(tmpns) == IS_STRING) {
 1862: 					inclusive_ns_prefixes[nscount++] = Z_STRVAL_PP(tmpns);
 1863: 				}
 1864: 				zend_hash_move_forward(Z_ARRVAL_P(ns_prefixes));
 1865: 			}
 1866: 			inclusive_ns_prefixes[nscount] = NULL;
 1867: 		} else {
 1868: 			php_error_docref(NULL TSRMLS_CC, E_NOTICE, 
 1869: 				"Inclusive namespace prefixes only allowed in exclusive mode.");
 1870: 		}
 1871: 	}
 1872: 
 1873: 	if (mode == 1) {
 1874: 		buf = xmlOutputBufferCreateFilename(file, NULL, 0);
 1875: 	} else {
 1876: 		buf = xmlAllocOutputBuffer(NULL);
 1877: 	}
 1878: 
 1879:     if (buf != NULL) {
 1880: 		ret = xmlC14NDocSaveTo(docp, nodeset, exclusive, inclusive_ns_prefixes,
 1881: 			with_comments, buf);
 1882: 	}
 1883: 
 1884: 	if (inclusive_ns_prefixes != NULL) {
 1885: 		efree(inclusive_ns_prefixes);
 1886: 	}
 1887: 	if (xpathobjp != NULL) {
 1888: 		xmlXPathFreeObject(xpathobjp);
 1889: 	}
 1890: 	if (ctxp != NULL) {
 1891: 		xmlXPathFreeContext(ctxp);
 1892: 	}
 1893: 
 1894:     if (buf == NULL || ret < 0) {
 1895:         RETVAL_FALSE;
 1896:     } else {
 1897: 		if (mode == 0) {
 1898: #ifdef LIBXML2_NEW_BUFFER
 1899: 			ret = xmlOutputBufferGetSize(buf);
 1900: #else
 1901: 			ret = buf->buffer->use;
 1902: #endif
 1903: 			if (ret > 0) {
 1904: #ifdef LIBXML2_NEW_BUFFER
 1905: 				RETVAL_STRINGL((char *) xmlOutputBufferGetContent(buf), ret, 1);
 1906: #else
 1907: 				RETVAL_STRINGL((char *) buf->buffer->content, ret, 1);
 1908: #endif
 1909: 			} else {
 1910: 				RETVAL_EMPTY_STRING();
 1911: 			}
 1912: 		}
 1913:     }
 1914: 
 1915: 	if (buf) {
 1916: 		int bytes;
 1917: 
 1918: 		bytes = xmlOutputBufferClose(buf);
 1919: 		if (mode == 1 && (ret >= 0)) {
 1920: 			RETURN_LONG(bytes);
 1921: 		}
 1922: 	}
 1923: }
 1924: /* }}} */
 1925: 
 1926: /* {{{ proto string DOMNode::C14N([bool exclusive [, bool with_comments [, array xpath [, array ns_prefixes]]]])
 1927:    Canonicalize nodes to a string */
 1928: PHP_METHOD(domnode, C14N)
 1929: {
 1930: 	dom_canonicalization(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
 1931: }
 1932: /* }}} */
 1933: 
 1934: /* {{{ proto int DOMNode::C14NFile(string uri [, bool exclusive [, bool with_comments [, array xpath [, array ns_prefixes]]]])
 1935:    Canonicalize nodes to a file */
 1936: PHP_METHOD(domnode, C14NFile)
 1937: {
 1938: 	dom_canonicalization(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
 1939: }
 1940: /* }}} */
 1941: 
 1942: /* {{{ proto int DOMNode::getNodePath()
 1943:    Gets an xpath for a node */
 1944: PHP_METHOD(domnode, getNodePath)
 1945: {
 1946: 	zval *id;
 1947: 	xmlNode *nodep;
 1948: 	dom_object *intern;
 1949: 	char *value;
 1950: 	
 1951: 	DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern);
 1952: 
 1953: 	value = xmlGetNodePath(nodep);
 1954: 	if (value == NULL) {
 1955: 		RETURN_NULL();
 1956: 	} else {
 1957: 		RETVAL_STRING(value, 1);
 1958: 		xmlFree(value);
 1959: 	}
 1960: }
 1961: /* }}} */
 1962: 
 1963: /* {{{ proto int DOMNode::getLineNo()
 1964:    Gets line number for a node */
 1965: PHP_METHOD(domnode, getLineNo)
 1966: {
 1967: 	zval *id;
 1968: 	xmlNode *nodep;
 1969: 	dom_object *intern;
 1970: 	
 1971: 	if (zend_parse_parameters_none() == FAILURE) {
 1972: 		return;
 1973: 	}
 1974: 
 1975: 	DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern);
 1976: 
 1977: 	RETURN_LONG(xmlGetLineNo(nodep));
 1978: }
 1979: /* }}} */
 1980: 
 1981: #endif
 1982: 
 1983: /*
 1984:  * Local variables:
 1985:  * tab-width: 4
 1986:  * c-basic-offset: 4
 1987:  * End:
 1988:  * vim600: noet sw=4 ts=4 fdm=marker
 1989:  * vim<600: noet sw=4 ts=4
 1990:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>