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