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

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