root/ext/dom/node.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dom_reconcile_ns
  2. dom_node_node_name_read
  3. dom_node_node_value_read
  4. dom_node_node_value_write
  5. dom_node_node_type_read
  6. dom_node_parent_node_read
  7. dom_node_child_nodes_read
  8. dom_node_first_child_read
  9. dom_node_last_child_read
  10. dom_node_previous_sibling_read
  11. dom_node_next_sibling_read
  12. dom_node_attributes_read
  13. dom_node_owner_document_read
  14. dom_node_namespace_uri_read
  15. dom_node_prefix_read
  16. dom_node_prefix_write
  17. dom_node_local_name_read
  18. dom_node_base_uri_read
  19. dom_node_text_content_read
  20. dom_node_text_content_write
  21. _php_dom_insert_fragment
  22. PHP_FUNCTION
  23. PHP_FUNCTION
  24. PHP_FUNCTION
  25. PHP_FUNCTION
  26. PHP_FUNCTION
  27. PHP_FUNCTION
  28. PHP_FUNCTION
  29. PHP_FUNCTION
  30. PHP_FUNCTION
  31. PHP_FUNCTION
  32. PHP_FUNCTION
  33. PHP_FUNCTION
  34. PHP_FUNCTION
  35. PHP_FUNCTION
  36. PHP_FUNCTION
  37. PHP_FUNCTION
  38. PHP_FUNCTION
  39. PHP_FUNCTION
  40. dom_canonicalization
  41. PHP_METHOD
  42. PHP_METHOD
  43. PHP_METHOD
  44. PHP_METHOD

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

/* [<][>][^][v][top][bottom][index][help] */